分组背包

分组背包问题的模型如下:
仍然先考虑原始线性DP的做法。为了满足“每组至多选择一个物品”,很自然的想法就是利用“阶段”线性增长的特征,把“物品组数”作为DP的“阶段”,只要使用了一个第i组的物品,就从第i个阶段的状态转移到第i+1个阶段的状态。

设F[i , j]表示从前i组中选出总体积为j的物品放入背包,物品的最大价值和。
在这里插入图片描述

代码片段:


memset(f, 0xcf, sizeof(f));
f[0] = 0;
for (int i = 1; i <= n; i++)
    for (int j = m; j >= 0; j--)
        for (int k = 1; k <= c[i]; k++)
            if (j >= v[i][k])
                f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);
                

除了倒序循环j之外,请格外留意,对于每一组内c[i]个物品的循环k应该放在j的内层。从背包的角度看,这是因为每组内至多选择一个物品,若把k置于j的外层,就会类似于多重背包,每组物品在F数组上的转移会产生累积,最终可以选择超过1个物品。从动态规划的角度,i是“阶段”,i与j共同构成“状态”,而k是“决策”——在第i组内使用哪一个物品,这三者的顺序绝对不能混淆。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值