多重背包的核心在把si拆分,这也是优化的思路
也是直接上ac代码(我直接给优化了,因为即使数据很小,但是用优化后的也是没有问题的):
#include <bits/stdc++.h>
using namespace std;
const int N = 2e4 + 5;
int dp[N];
int v[N], w[N], s[N];
int n, m;
int a[N], b[N];
int cnt;
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 <= s[i]; j *= 2) {//按照二进制拆分如果最后数据不是二进制则出循环,单独写入
//原理:例如‘6’差分为1,2,3,当取1时就是只拿一个的情况,想要拿4个即是拿一个1,再拿一个3,所以可以把所有情况都枚举一遍
s[i] -= j;
cnt++;
a[cnt] = v[i] * j;
b[cnt] = w[i] * j;
}
if (s[i] > 0) {
cnt++;
a[cnt] = v[i] * s[i];
b[cnt] = w[i] * s[i];
}
}
for (int i = 1; i <= cnt; i++) {//这就转化为01背包了
for (int j = m; j >= a[i]; j--) {
dp[j] = max(dp[j], dp[j - a[i]] + b[i]);
}
}
cout << dp[m] << endl;
return 0;
}