思路:
由于一个数一定可以由一个二进制数表示,所以可以把每一种物品的相应数量放在若干个箱子,分别放1,2,4 ,8,16…直到这种物品全都分配到箱子中,最后一个箱子不一定是2的倍数。
然后每个箱子里面的相同物品总体相加看成一种物品,对这个箱子的体积和价值初始化
* 最后箱子数看成物品总数,进行01背包,选或者不选
#include<iostream>
#include<algorithm>
using namespace std;
// 11*1000
const int N = 11050;
int n, V, v[N], w[N],cnt = 0,f[N];
int main(){
cin >> n >> V;
f[0] = 0;
for(int i = 1; i <= n; i++){
int x, y, z, k = 1;
cin >> x >> y >> z;
while(z>=k){
cnt++;
v[cnt] = k * x;
w[cnt] = k * y;
// cout << k <<" " << v[cnt] <<endl;
z -= k;
k <<= 1;
}
if(z > 0){
cnt++;
v[cnt] = z * x;
// cout << z <<" " << v[cnt] <<endl;
w[cnt] = z * y;
}
}
n = cnt;
// for(int i = 1; i <= n; i++ )
// cout<<w[i] <<endl;
for(int i = 1; i <= n; i++){
for(int j = V; j >= v[i]; j--){
f[j] = max(f[j], f[j - v[i]] + w[i]);
// cout << i << "!" << f[j] <<endl;
}
}
cout << f[V] <<endl;
return 0;
}