AcWing 7. 混合背包问题:发现可以全部打包成01背包来做,不用考虑完全背包
原题链接
中等
作者:
Sean今天AC了吗
,
2020-08-18 22:28:30
,
所有人可见
,
阅读 706
无论是何种背包,直接打包成01背包来做
#include <iostream>
using namespace std;
const int N = 510, M = 1010, S = 12000;
int f[M];
int n, m;
int v[S], w[S], s[N];
int main(){
cin >> n >> m;
int cnt = 0;
for(int i = 1; i <= n; i ++){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
// 全部打包成01背包来做
if(c == -1){
cnt ++;
v[cnt] = a;
w[cnt] = b;
}else if(c > 0){
int k = 1;
while(k <= c){
cnt ++;
v[cnt] = k * a;
w[cnt] = k * b;
c -= k;
k *= 2;
}
if(c > 0){
cnt ++;
v[cnt] = c * a;
w[cnt] = c * b;
}
}else{
int z = 0;
while(z * a <= m) z ++;
int k = 1;
while(k <= z){
cnt ++;
v[cnt] = k * a;
w[cnt] = k * b;
z -= k;
k *= 2;
}
if(z > 0){
cnt ++;
v[cnt] = c * a;
w[cnt] = c * b;
}
}
}
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] << endl;
return 0;
}