首先可以将多重背包的每一种物品的数量都看做一种物品,这样就转化成了01背包。但是由于数据过大会超时。
所以在这里采用二进制的优化,可以使用二进制将其某种物品的数量捆绑成1,2,4,8.。。。。。。这样可以将表示的数量缩短。
然后采用01背包的做法即可。
#include <bits/stdc++.h>
using namespace std;
struct Node{
int weight;
int value;
} node[2000+10];
int dp[2000+10];
int main() {
int n, t;
int x, w, v, cnt = 1;
cin>>n>>t;
for (int i=1;i<=n;i++) {
cin>>x>>w>>v;
int k = 1;
while ((k<<1)+1<=x) {
k = (k<<1)+1;
}
int num = 1, temp = k;
while (k) {
node[cnt].weight = w*num;
node[cnt].value = v*num;
num = num*2;
cnt++;k = (k>>1);
}
if (x>temp) {
node[cnt].weight = w*(x-temp);
node[cnt].value = v*(x-temp);
cnt++;
}
}
for (int i=1;i<=cnt;i++) {
for (int j=t;j>=node[i].weight;j--) {
dp[j] = max(dp[j], dp[j-node[i].weight]+node[i].value);
}
}
cout<<dp[t];
return 0;
}

京公网安备 11010502036488号