背包九讲学习笔记 第六讲-分组的背包问题

第六讲-分组的背包问题

题目

有n件物品可以被放入一个容量为v的背包中,每件物品体积为volume[i],价值为value[i].此外,这些物品被分成p组,每组中的物品最多只能选一件,求背包中最多可以装多少价值的物品.

分析

对于每组物品,可以选择这组物品中某一件,或者这组中一件也不选.
是不是感觉这个东西有点像,01背包?
如果用dp(k,v)表示前k组物品最多在容量为v的背包中装多少价值,那么显然
dp(k,v)=max(dp(k-1,v),dp(k-1,v-volume[i])+value[i]),其中i遍历第k个物品集合.

实现

for(int k=1;k<=p;k++)
for(int j=v;j>=0;j–) //此处遍历顺序与物品种类有关
for(int i:part[k])
dp[j]=max(dp[j],dp[j-volume[i]]+value[i]).
注意遍历方式一定是kji,如果是kij的话就无法保证每组只选一个了.
先j再i保证了每组内,每个体积只会被一个最优的物品访问到.

优化

这里可用第二讲完全背包中的对应优化
1.n^2遍历,将体积大价值小的物品去掉.
2.计数排序,去掉体积大于v的物品,相同体积的物品只取价值最大的.(限制物品个数大于体积的情况?)

其他

一点自己的看法
以上得思考都是基于01背包来做的,那么其他呢?
如果每组可以取无限次,每次取的物品可以不一样:分组就没有意义了,对所有物品完全背包即可.
如果每组可以取无限次,每次取的物品必须相同: 这是什么问题?想不出来,先略.

训练题

见后文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值