[经典] 背包问题(二)

【6】分组背包

有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 

主要是对01背包的原始循环进行理解,外层i代表了物品的遍及数,内层代表了动规基本单元,增加一个分组,通过v内层限制,由于是从V到v遍历,里面最大值只会使用一个。动态规划方程为f[k][v]=max{f[k-1][v],f[k-1][v-c[i]]+w[i],物品i属于组k}。伪代码是

for 所有的组k   
    for v=V..0 
        for 所有的i属于组k 
            f[v]=max{f[v],f[v-c[i]]+w[i]}

【7】依赖背包

通过构造分组背包来完成。比如如果有一个主件,它最多有两个附件。那么这样一个情况就可以看成一个组:一个物品是主件,第二个是主件+附件A,第三个是主件+附件B,第四个是主件+两个附件,四个物品最多选一件,也可以都不选。 

更一般的,情况更加复杂,

【8】泛化背包

考虑这样一种物品,它并没有固定的费用和价值,而是它的价值随着你分配给它的费用而变化。一个泛化物品就是一个数组h[0..V],给它费用v,可得到价值h[V]。通过泛化物品,可以对前面的7个背包问题做一个高度更高的理解:

一个费用为c价值为w的物品,如果它是01背包中的物品,那么把它看成泛化物品,它就是除了h(c)=w其它函数值都为0的一个函数。如果它是完全背包中的物品,那么它可以看成这样一个函数,仅当v被c整除时有h(v)=v/c*w,其它函数值均为0。如果它是多重背包中重复次数最多为n的物品,那么它对应的泛化物品的函数有h(v)=v/c*w仅当v被c整除且v/c<=n,其它情况函数值均为0。 一个物品组可以看作一个泛化物品h。对于一个0..V中的v,若物品组中不存在费用为v的的物品,则h(v)=0,否则h(v)为所有费用为v的物品的最大价值。P07中每个主件及其附件集合等价于一个物品组,自然也可看作一个泛化物品。

求解某个泛化物品的一种方法就是将它表示为若干泛化物品的和然后求之。如两个泛化物品的背包问题动规方程为:f(v)=max{h(k)+l(v-k)|0<=k<=v}

posted @ 2016-04-26 15:55  CarlGoodman  阅读(265)  评论(0编辑  收藏  举报