对每一种物品的每个分别用0/1背包去求
代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int T;
cin >> T; // 读入测试数据的数量T
while (T--) {
int n, c;
cin >> n >> c; // 读入物品数量n和背包容量c
vector<int> w(n), v(n), m(n); // 分别保存每个物品的重量w、价值v和数量m
for (int i = 0; i < n; i++) {
cin >> w[i] >> v[i] >> m[i]; // 读入每个物品的信息
}
vector<int> dp(c + 1, 0); // 初始化大小为c+1的数组dp,dp[j]表示在容量不超过j的情况下,能够获得的最大价值
for (int i = 0; i < n; i++) { // 枚举每个物品
for (int k = 1; m[i] > 0; k <<= 1) { // 使用二进制分组的方式,将物品i的数量m[i]分解成若干个2的幂次方
int cnt = min(m[i], k); // 如果幂次方k小于等于m[i],则选取k个物品;否则,只选取m[i]个物品
m[i] -= cnt; // 将选取的物品从m[i]中减去
for (int j = c; j >= cnt * w[i]; j--) { // 0/1背包的思想,从大到小遍历容量j
dp[j] = max(dp[j], dp[j - cnt * w[i]] + cnt * v[i]); // 更新dp[j]
}
}
}
cout << dp[c] << endl; // 输出dp[c]即为答案
}
return 0;
}
图解: