1、找出拿相同颜色且糖果总数最多的3位小朋友
题目
代码
ac。思路:按题目要求先排序,再输出即可。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <map>
#include <unordered_map>
#include "limits.h"
#include "math.h"
using namespace std;
bool cmp(pair<int, int> a, pair<int, int> b){
if( a.second == b.second ){
return a.first < b.first;
}
return a.second > b.second;
}
int main(int argc, const char * argv[]) {
int n;
cin >> n;
//序号、糖果数
vector<pair<int, int> > red;
vector<pair<int, int> > blue;
int num,color;
for(int i=1; i<=n; i++){
cin >> num >> color;
if( color == 1 ){
red.push_back({i,num});//序号、糖果数
}else{
blue.push_back({i,num});//序号、糖果数
}
}
//判断个数
if( red.size()<3 && blue.size()<3 ){
cout << "null" << endl;
return 0;
}
//按糖果数降序排序
int total1 = 0, xuhao1 = 1025;
if( red.size()>=3 ){
sort( red.begin(), red.end(), cmp);
xuhao1 = red[0].first;
for(int i=0; i<3; i++){
total1 += red[i].second;
}
}
int total2 = 0, xuhao2 = 1025;
if( blue.size()>=3 ){
sort( blue.begin(), blue.end(), cmp);
xuhao2 = blue[0].first;
for(int i=0; i<3; i++){
total2 += blue[i].second;
}
}
//比较并输出
if( total1 > total2 || (total1==total2 && xuhao1<xuhao2) ){
cout << red[2].first << " " << red[1].first << " " << red[0].first << endl;
cout << 1 << endl;
cout << total1 << endl;
}else{
cout << blue[2].first << " " << blue[1].first << " " << blue[0].first << endl;
cout << 2 << endl;
cout << total2 << endl;
}
return 0;
}
2、求湖泊个数
题目
代码
原题:leetcode200.岛屿个数 之前写过思路。dfs / bfs都可以。此处用dfs方法ac
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <map>
#include <unordered_map>
#include "limits.h"
#include "math.h"
using namespace std;
vector<string> nums;
int nrows,ncols;
void dfs(int i, int j){
if( i<0 || j<0 || i>=nrows || j>=ncols || nums[i][j] == 'H' ){
return;
}
if( nums[i][j] == 'S' ){
nums[i][j] = 'H';
//四个方向bfs
dfs(i-1, j);
dfs(i+1, j);
dfs(i, j-1);
dfs(i, j+1);
}
}
int main(int argc, const char * argv[]) {
string str;
cin >> str;
//处理行数、列数
string word = "";
for(int i=0; i<str.length(); i++){
if( str[i]==',' ){
nrows = stoi(word);
word = "";
}else{
word += str[i];
}
}
ncols = stoi(word);
//输入
for(int i=0; i<nrows; i++){
cin >> str;
nums.push_back(str);
}
//bfs
int anws = 0;
for(int i=0; i<nrows; i++){
for(int j=0; j<ncols; j++){
if( nums[i][j]=='S' ){
anws++;
dfs(i,j);
}
}
}
cout << anws << endl;
return 0;
}
3、最大体积最大价值的01背包
题目
思路
以下代码是普通的01背包解法,只能ac80%,考虑的是总体积不超过背包容量的前提下求最大价值,但是题设中要求空间占用最大。
- 普通的01背包解法,dp[i][j]表示在箱子尺寸为j的前提下,在[0,i]的箱子中选择所能达到的最大价值。状态转移方程:对于第i个箱子,每次可选择放或不放,放则最大价值为dp[i-1][j-weights[i-1]] + value[i-1];不放则最大价值为dp[i-1][j]。dp[i][j]取两者最大值。最后输出dp[n][target]
- 根据题设,那我定义dp[i][j]表示在保证箱子体积j被塞满的前提下,在[0,i]的箱子中选择所能达到的最大价值。状态转移方程:对于第i个箱子,如果体积j-weights[i-1]刚好被塞满的值不为0,那就可以把第i个箱子放进去,dp[i][j] = max(dp[i][j],dp[i-1][j-weights[i-1]] + value[i-1] )。最后如果dp[n][target]不为0则输出,否则依次判断并输出dp[n][target-1]、dp[n][target-2]…。
- 不同的地方在于多了一个判断条件!上一个是否为0!为0就不能放。
常规01背包解法
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <map>
#include <unordered_map>
#include "limits.h"
#include "math.h"
using namespace std;
int main(int argc, const char * argv[]) {
int target, n; //卡车空间、箱子个数
cin >> target >> n;
//每个箱子的尺寸、价值
int weights[n];
int value[n];
for(int i=0; i<n; i++){
cin >> weights[i];
}
for(int i=0; i<n; i++){
cin >> value[i];
}
/*
1、dp[i][j]表示在箱子尺寸为j的前提下,在[0,i]的箱子中选择所能达到的最大价值。
2、状态转移方程:对于第i个箱子,每次可选择放或不放.
放则最大价值为dp[i-1][j-weights[i-1]] + value[i-1];
不放则最大价值为dp[i-1][j]。取最大值。同时注意可以降维压缩空间。
3、初始状态dp[...][0]=0。求dp[n][target]
*/
int dp[n+1][target+1];
//初始化
for(int i=0; i<=n; i++){
for(int j=0 ;j<=target; j++){
dp[i][j] = 0;
}
}
for(int i=1; i<=n; i++){
for(int j=1; j<=target; j++){
if( j >= weights[i-1] ){
//放 or 不放
dp[i][j] = max(dp[i-1][j-weights[i-1]] + value[i-1], dp[i-1][j]);
}else{
dp[i][j] = dp[i-1][j];
}
}
}
cout << dp[n][target] << endl;
return 0;
}
空间降维的普通01背包解法
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <map>
#include <unordered_map>
#include "limits.h"
#include "math.h"
using namespace std;
int main(int argc, const char * argv[]) {
int target, n; //卡车空间、箱子个数
cin >> target >> n;
if( target==0 || n==0 ){
cout << 0 << endl;
return 0;
}
//每个箱子的尺寸、价值
int weights[n];
int value[n];
for(int i=0; i<n; i++){
cin >> weights[i];
}
for(int i=0; i<n; i++){
cin >> value[i];
}
/*
1、dp[i][j]表示在箱子尺寸为j的前提下,在[0,i]的箱子中选择所能达到的最大价值。
2、状态转移方程:对于第i个箱子,每次可选择放或不放.
放则最大价值为dp[i-1][j-nums[i].first] + nums[i].second;
不放则最大价值为dp[i-1][j]。取最大值。同时注意可以降维压缩空间。
3、初始状态dp[...][0]=0。求dp[n][target]
*/
int dp[target+1];
//初始化
for(int i=0; i<=target; i++){
dp[i] = 0;
}
for(int i=1; i<=n; i++){
for(int j=target; j>=weights[i-1]; j--){
dp[j] = max(dp[j-weights[i-1]] + value[i-1], dp[j]);
}
}
cout << dp[target] << endl;
return 0;
}
最大体积的最大价值01背包解法
根据上述思路自己写的,测试用例能过,不知道能不能ac。感觉思路没问题。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <map>
#include <unordered_map>
#include "limits.h"
#include "math.h"
using namespace std;
int main(int argc, const char * argv[]) {
int target, n; //卡车空间、箱子个数
cin >> target >> n;
//每个箱子的尺寸、价值
int weights[n];
int value[n];
for(int i=0; i<n; i++){
cin >> weights[i];
}
for(int i=0; i<n; i++){
cin >> value[i];
}
/*
定义dp[i][j]表示在保证箱子体积j被塞满的前提下,在[0,i]的箱子中选择所能达到的最大价值。
状态转移方程:对于第i个箱子,如果体积j-weights[i-1]刚好被塞满的值不为0,那就可以把第i个箱子放进去,
dp[i][j] = max(dp[i][j],dp[i-1][j-weights[i-1]] + value[i-1] )。
最后如果dp[n][target]不为0则输出,否则依次判断并输出dp[n][target-1]、dp[n][target-2]…。初始状态dp[...][0]=0。求dp[n][target]
不同的地方在于多了一个判断条件!上一个是否为0!为0就不能放。
*/
int dp[n+1][target+1];
//初始化
for(int i=0; i<=n; i++){
for(int j=0 ;j<=target; j++){
dp[i][j] = 0;
}
}
for(int i=1; i<=n; i++){
for(int j=1; j<=target; j++){
//1、当前体积不够,那就在把当前元素放入,剩下的也要被塞满; 2、 整个体积刚好能塞当前这一个
if( (j > weights[i-1] && dp[i-1][j-weights[i-1]] !=0) || (j == weights[i-1]) ){
//放 or 不放
dp[i][j] = max(dp[i-1][j-weights[i-1]] + value[i-1], dp[i-1][j]);
}else{
dp[i][j] = dp[i-1][j];
}
}
}
//输出最大体积的最大价值
for(int i=target; i >= 0; i-- ){
if( dp[n][i] > 0 ){
cout << dp[n][i] << endl;
break;
}
}
// cout << dp[n][target] << endl;
return 0;
}