2022.3.12#完全背包问题
2022-03-12
实际上就是无限物品的01背包问题。
1.二维数组方法
与01背包不同的地方在于,01背包是通过检验max【bag[i-1][j],bag[i-1][j-something[i].weight]+something[i].val】,它的思想都是基于上一次取的物品,不可以基于本次,因为一个物品只能有一个嘛,而完全背包则不同在,它对比取我本身和不取,因为取上一次的物品可以看成之前的我选择不取,继承了上一次的物品,然后后来的我选择取我本身!
1 #include<iostream> 2 #include<vector> 3 #define maxn 100010 4 using namespace std; 5 typedef struct thing{ 6 int val; 7 int wgt; 8 }things; 9 int bagmax; 10 vector<things>smthing(1); 11 12 void pre(vector<vector<int> >bag) 13 { 14 for(int i=1;i<bagmax;i++) 15 if(i>=smthing[1].wgt) 16 bag[1][i]=smthing[1].val; 17 } 18 int main(void) 19 { 20 ios_base::sync_with_stdio(0); 21 cin.tie(0); 22 cin>>bagmax; 23 int n; 24 cin>>n; 25 while(n--) 26 { 27 things temp; 28 cin>>temp.wgt>>temp.val; 29 smthing.push_back(temp); 30 } 31 vector<vector<int> >bag(smthing.size()+1,vector<int>(bagmax+1,0)); 32 pre(bag); 33 34 for(int i=1;i<smthing.size();i++) 35 for(int j=1;j<=bagmax;j++) 36 if(j<smthing[i].wgt) 37 bag[i][j]=bag[i-1][j]; 38 else 39 bag[i][j]=max(bag[i-1][j],bag[i][j-smthing[i].wgt]+smthing[i].val); 40 41 cout<<bag[smthing.size()-1][bagmax]<<endl; 42 return 0; 43 44 }
2.一维数组方法
该方法无所谓for循环的内外,不同点在于对背包的遍历,它是从前往后的,与01背包相反,从后往前就是为了避免重复,此时从前往后再好不过。
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 int maxn; 5 int n; 6 typedef struct thing{ 7 int val; 8 int wgt; 9 }things; 10 vector<things>smthing(1); 11 int main(void) 12 { 13 ios_base::sync_with_stdio(0); 14 cin.tie(0); 15 cin>>n>>maxn; 16 while(n--) 17 { 18 things temp; 19 cin>>temp.wgt>>temp.val; 20 smthing.push_back(temp); 21 } 22 vector<int> bag(maxn+1,0); 23 for(int i=1;i<=maxn;i++) 24 if(i>=smthing[1].wgt) 25 bag[i]=smthing[1].val; 26 27 for(int i=1;i<smthing.size();i++) 28 for(int j=smthing[i].wgt;j<=maxn;j++) 29 bag[j]=max(bag[j],bag[j-smthing[i].wgt]+smthing[i].val); 30 31 cout<<bag[maxn]<<endl; 32 return 0; 33 }

浙公网安备 33010602011771号