2022.3.12 01背包问题
2022-03-12
背包容量bagmaxn,物品总数something.size(),物品价值val,物品重量wgt
bag[i][j]:i是前几个物品,j是包包容量多少时
1.二维数组方式:
无所谓背包物品谁先遍历,习惯先物品再背包,初始化无所谓,背包遍历从前往后可以,因为二维数组方式是对bag[i-1][j]进行推演讨论。
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 typedef struct thing{ 5 int wgt; 6 int val; 7 }things; 8 int bagmax; 9 void pre(vector<vector<int> >&bag,vector<things> something) 10 { 11 for(int i=1;i<=bagmax;i++) 12 if(i>=something[1].wgt) 13 bag[1][i]=something[1].val; 14 } 15 int main(void) 16 { 17 ios_base::sync_with_stdio(0); 18 cin.tie(0); 19 cin>>bagmax; 20 vector<things> something(1); 21 int n; 22 cin>>n; 23 while(n--) 24 { 25 things temp; 26 cin>>temp.wgt>>temp.val; 27 something.push_back(temp); 28 } 29 vector<vector<int> >bag(something.size(),vector<int>(bagmax+1,0)); 30 pre(bag,something); 31 32 for(int i=1;i<something.size();i++) 33 for(int j=1;j<=bagmax;j++) 34 if(j<something[i].wgt) 35 bag[i][j]=bag[i-1][j]; 36 else 37 bag[i][j]=max(bag[i-1][j],bag[i-1][j-something[i].wgt]+something[i].val); 38 39 cout<<bag[something.size()-1][bagmax]<<endl; 40 return 0; 41 }
2.一维数组方法
将每次的bag[i-1]直接copy到bag[i]上,这样可以省一个纬度,此时要注意,必须是外物品内背包,而且背包遍历时需要从后往前。
如果不这样,第一个会错在同一个物品出现多次,第二个会错在每个bag[j]背包只会放进一个物品。
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 typedef struct thing{ 5 int wgt; 6 int val; 7 }things; 8 int bagmax; 9 void pre(vector<int>bag,vector<things>something) 10 { 11 for(int i=1;i<=bagmax;i++) 12 { 13 if(i>=something[1].wgt) 14 bag[i]=something[1].val; 15 } 16 } 17 int main(void) 18 { 19 ios_base::sync_with_stdio(0); 20 cin.tie(0); 21 cin>>bagmax; 22 vector<things> something(1); 23 int n; 24 cin>>n; 25 while(n--) 26 { 27 things temp; 28 cin>>temp.wgt>>temp.val; 29 something.push_back(temp); 30 } 31 vector<int>bag(bagmax+1,0); 32 33 for(int i=1;i<something.size();i++) 34 for(int j=bagmax;j>=something[i].wgt;j--) 35 bag[j]=max(bag[j],bag[j-something[i].wgt]+something[i].val); 36 37 cout<<bag[bagmax]<<endl; 38 return 0; 39 }

浙公网安备 33010602011771号