分组背包问题
目录
1——问题概览
2——处理"分组"
问题概览
难度:普及 题目:YBT1272 分组背包模版
本文以YBT1272 分组背包模版作为讲解
题目描述:
一个旅行者有一个最多能装VVV公斤的背包,现在有nnn件物品,它们的重量分别是W1,W2,...,WnW_1,W_2,...,W_nW1 ,W2 ,...,Wn
它们的价值分别为C1,C2,...,CnC_1,C_2,...,C_nC1 ,C2 ,...,Cn 。这些物品被划分为若干组P1,P2,...,PTP_1,P_2,...,P_TP1 ,P2 ,...,PT ,每组中的物品互相冲突,最多选一件。
求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
处理"分组"
分组背包不同于01背包,它限定了小组,问题就变为了是选择这个小组中的某一件,还是都不选
按照01背包的原理我们可以很容易定义出DPDPDP表的状态,DP[p][j]DP[p][j]DP[p][j]为第ppp组且可用空间为jjj下所能获得的最大价值
设若物品iii为ppp组中的,则状态转移方程就是DP[p][j]=max(DP[p−1][j],DP[p][j−i.W]+i.C)DP[p][j]=max(DP[p-1][j],DP[p][j-i.W]+i.C)DP[p][j]=max(DP[p−1][j],DP[p][j−i.W]+i.C)
当然,分组背包也是可以优化到一维DP[j]=max(DP[j],DP[j−i.W]+i.C)DP[j]=max(DP[j],DP[j-i.W]+i.C)DP[j]=max(DP[j],DP[j−i.W]+i.C)
在遍历操作的时候开三层的循环,枚举小组,可用容量还有组内的每一个物品
注意枚举容量应在枚举组内物品外层,因为要保证一组中只有一个物品被拿,不然会出现01背包优化后采用顺推的情况,那样就是完全背包了
就像01背包的优化后是采用逆推保证它只拿一次,分组背包没采用逆推而是改变循环层序起到保证的效果
详解在注释里,实现代码如下: