《dp补卡——多重背包》

193 阅读1分钟

多重背包简介:
有N种物品和一个容量为V的背包。第i种物品最多有Mi件可用,每件耗费的空间为Ci,价值为Wi。求解将哪些物品装入背包可使得这些物品耗费的空间总和不超过背包容量,且价值总和最大。
将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;
    //进行展开,转化为01背包问题
    for(int i = 0; i < nums.size(); i++)
    {
        while(nums[i] > 1)	
        {
            //nums[i]保留到1,把其他的多余的个数展开
            weight.push_back(weight[i]);
            value.push_back(value[i]);
            nums[i]--;
        }
    }
    vector<int> dp(bagWeight + 1, 0);
    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]] + values[i])
        }
    }
	cout << dp[bagWeight] << endl;
}