皆转为多重背包
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1e6 + 10;
int f[N];
int v[N],w[N];
int cnt;
int n,m;
int main(){
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++){
int vv,ww,ss;
cin >> vv >> ww >> ss;
if(ss == -1) ss = 1;
else if(ss == 0) ss = m/vv;//将完全背包转为多重背包
int k = 1;
// cout << "ss =" << ss << endl;
while(k <= ss){
cnt++;
v[cnt] = k*vv;
w[cnt] = k*ww;
ss -= k;
k *= 2;
}
if(ss > 0){
cnt++;
v[cnt] = ss*vv;
w[cnt] = ss*ww;
}
// cout <<"cnt=" << cnt << endl;
}
for(int i = 1; i <= cnt; i++){
for(int j = m; j >= v[i]; j--){
f[j] = max(f[j],f[j - v[i]] + w[i]);
}
}
cout << f[m] << endl;
return 0;
}
根据ss的值,来选用不同的背包策略
或许代码,有bug。
因最后一个1000的样例,输出和标准答案不一样,但是ac了。。。
思路应该没问题
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1e3 + 10, M = 1e3 + 10;
int f[N];
int g[N];
int ff[N];
int v[N],w[N],s[N];
int n,m;
int main(){
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++){
int vv,ww,ss;
scanf("%d%d%d",&vv,&ww,&ss);
if(ss == -1){
for(int j = m; j >= vv; j--){
f[j] = max(f[j], f[j - vv] + ww);
}
}
else if(ss == 0){
for(int j = vv; j <= m; j++){
f[j] = max(f[j],f[j - vv] + ww);
}
}
else if(ss > 0){
int k = 1;
int cnt = 0;
while(k <= ss){
cnt++;
v[cnt] = k * vv;
w[cnt] = k * ww;
ss -= k;
k *= 2;
}
if(ss > 0){
cnt++;
v[cnt] = ss * vv;
w[cnt] = ss * ww;
}
for(int k = 1; k <= cnt; k++){
for(int j = m; j >= v[k]; j--){
f[j] = max(f[j],f[j - v[k]] + w[k]);
}
}
//for(int j = m; j >= vv; j--){
// for(int k = 0; k <= ss && k * vv <= j; k++){
// f[j] = max(f[j], f[j - k*vv] + k * ww);
// }
// }
}
}
cout << f[m] << endl;
return 0;
}