多重背包问题有N种物品和容量为V的背包,第i种物品最多有Mi件可用,每件物品占空间为Ci,价值为Wi,求解哪些物品放入背包可使价值总和最大。
多重背包问题可以转化为01背包问题,将多重背包问题中的Mi件物品摊开就是一个01背包问题,且每个物品只用一次,实现代码如下:
void test_multi_pack() {
vector<int> weight = {1,3,4};
vector<int> value = {15,20,30};
vector<int> nums = {2,3,2};
int bagWeight = 10;
for(int i = 0; i<nums.size(); i++) {
//把物品展开
while(nums[i] > 1) {
weight.push_back(weight[i]);
value.push_back(value[i]);
nums[i]--;
}
}
//1.dp数组及下标含义
//dp[j]为重量为j的背包能盛的最大价值
//3.dp数组初始化
vector<int> dp(bagWeight+1, 0);
//2.递推公式
//4.遍历顺序
for (int i = 0; i<weight.size(); i++) {//遍历物品
for(int j = bagWeight; j>=weight[i]; j--) { //遍历背包容量
dp[j] = max(dp[j], dp[j-weight[i]] + value[i]);
}
}
cout << dp[bagWeight] << endl;
//5.举例推导dp数组
}
int main() {
test_multi_pack();
}