多重背包和完全背包的唯一区别就是多重的每个物品有数量,而完全是每个物品无限取。
所以最朴素的算法很容易就写出来了
#include <bits/stdc++.h>
using namespace std;
const int N=1890;
int v[N],s[N],w[N],n,m,f[N][N];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>v[i]>>w[i]>>s[i];
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=0;k*v[i]<=j&&k<=s[i];k++){
f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+w[i]*k);
}
}
}
cout<<f[n][m];
return 0;
}
朴素算法讲完当然就是优化了
二维变一维的方法:
#include <bits/stdc++.h>
using namespace std;
const int N=1890;
int f[N];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
int v,w,s;
cin>>v>>w>>s;
for(int j=m;j>=v;j--){
for(int k=0;k<=s&&k*v<=j;k++){
f[j]=max(f[j],f[j-k*v]+w*k);
}
}
}
cout<<f[m];
return 0;
}
优化2:
相信大家应该都知道二进制,任何一些数都可以用二进制表示,物品个数也一样。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N=2501;
int f[N],v[N],w[N];
int n,m;
int main(){
cin>>n>>m;
int cnt=0;
for(int i=1;i<=n;i++){
int a,b,s;
cin>>a>>b>>s;
int k=1;
while(k<=s){
cnt++;
v[cnt]=a*k;
w[cnt]=b*k;
s-=k;
k+=k;
}
if(s){
cnt++,v[cnt]=a*s,w[cnt]=b*s;
}
}
n=cnt;
for(int i=1;i<=n;i++)
for(int j=m;j>=v[i];j--)
f[j]=max(f[j],f[j-v[i]]+w[i]);
cout<<f[m];
return 0;
}