为了解决这个问题,我们可以使用一种称为“二进制优化”的方法,将每种物品的数量限制转换为二进制形式,这样可以将多重背包问题转化为0-1背包问题,从而可以使用动态规划来解决。
以下是C++代码实现:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 定义一个结构体来存储物品的信息
struct Item {
int value;
int weight;
int count; // 数量限制
};
int main() {
int N, W;
cin >> N >> W;
vector<Item> items;
for (int i = 0; i < N; ++i) {
int v, w, m;
cin >> v >> w >> m;
// 将每种物品的数量限制转换为二进制形式
for (int k = 1; k <= m; k <<= 1) {
items.push_back({v * k, w * k, k});
m -= k;
}
if (m > 0) {
items.push_back({v * m, w * m, m});
}
}
// 动态规划数组,dp[i] 表示容量为i时的最大价值
vector<int> dp(W + 1, 0);
// 遍历所有物品
for (const auto& item : items) {
for (int j = W; j >= item.weight; --j) {
// 更新背包容量为j时的最大价值
dp[j] = max(dp[j], dp[j - item.weight] + item.value);
}
}
// 输出最大价值
cout << dp[W] << endl;
return 0;
}
Copy
这段代码首先读取物品的数量N和背包的容量W,然后读取每个物品的价值、重量和限制,并将每种物品的数量限制转换为二进制形式。接着,它使用一个一维数组dp
来存储在不同背包容量下的最大价值。对于每种物品,它都会尝试不同的数量,并更新背包容量从0到W的所有可能情况下的最大价值。最后,它输出在背包容量为W时的最大价值。
这种方法的时间复杂度是O(N * logM * W),其中N是物品的数量,M是每种物品的数量限制,W是背包的容量。