有依赖的背包问题(背包九讲)

问题:

        这样的背包问题的物品间存在某种“依赖”的关系。也就是说,i依赖于j,表示若选物品i,则必须选物品j。为了简化起见,我们先设没有某个物品既依赖于别的物品,又被别的物品所依赖;另外,没有某件物品同一时候依赖多件物品。

算法:

        这个问题由NOIP2006金明的预算方案一题扩展而来。遵从该题的提法,将不依赖于别的物品的物品称为“主件”,依赖于某主件的物品称为“附件”。由这个问题的简化条件可知全部的物品由若干主件和依赖于每一个主件的一个附件集合组成。依照背包问题的一般思路,仅考虑一个主件和它的附件集合。但是,可用的策略许多,包含:一个也不选,仅选择主件,选择主件后再选择一个附件,选择 主件后再选择两个附件……无法用状态转移方程来表示如此多的策略。(其实,设有n个附件,则策略有2^n+1个,为指数级。)考虑到全部这些策略都是相互排斥的(也就是说,你只能选择一种策略),所以一个主件和它的附件集合实际上相应于P06中的一个物品组,每一个选择了主件又选择了若干个附件的策略相应于这个物品组中的一个物品,其费用和价值都是这个策略中的物品的值的和。但不过这一步转化并不能给出一个好的算法,由于物品组中的物品还是像原问题的策略一样多。再考虑P06中的一句话:能够对每组中的物品应用P02中“一个简单有效的优化”。 这提示我们,对于一个物品组中的物品,全部费用同样的物品仅仅留一个价值最大的,不影响结果。所以,我们能够对主件i的“附件集合”先进行一次01背包,得到费用依次为0..V-c[i]全部这些值时对应的最大价值f'[0..V-c[i]]。那么这个主件及它的附件集合相当于V-c[i]+1个物品的物品 组,当中费用为c[i]+k的物品的价值为f'[k]+w[i]。也就是说原来指数级的策略中有非常多策略都是冗余的,通过一次01背包后,将主件i转化为 V-c[i]+1个物品的物品组,就能够直接应用P06的算法解决这个问题了。

较一般的问题:

        更一般的问题是:依赖关系以图论中“森林”的形式给出(森林即多叉树的集合),也就是说,主件的附件仍然能够具有自己的附件集合,限制仅仅是每一个物品最多仅仅依赖于一个物品(仅仅有一个主件)且不出现循环依赖。解决问题仍然能够用将每一个主件及其附件集合转化为物品组的方式。唯一不同的是,因为附件可能还有附件,就不能将每一个附件都看作一个一般的01背 包中的物品了。若这个附件也有附件集合,则它必然要被先转化为物品组,然后用分组的背包问题解出主件及其附件集合所相应的附件组中各个费用的附件所相应的价值。其实,这是一种树形DP,其特点是每一个父节点都须要对它的各个儿子的属性进行一次DP以求得自己的相关属性。这已经触及到了“泛化物品”的思想。看完P08后,你会发现这个“依赖关系树”每一个子树都等价于一件泛化物品,求某节点为根的子树相应的泛化物品相当于求其全部儿子的相应的泛化物品之和。

小结:

        NOIP2006的那道背包问题我做得非常失败,写了上百行的代码,却一分未得。后来我通过思考发现通过引入“物品组” 和“依赖”的概念能够加深对这题的理解,还能够解决它的推广问题。用物品组的思想考虑那题中极其特殊的依赖关系:物品不能既作主件又作附件,每一个主件最多 有两个附件,能够发现一个主件和它的两个附件等价于一个由四个物品组成的物品组,这便揭示了问题的某种本质。

        我想说:失败不是什么丢人的事情,从失败中全无收获才是。

--------------------------------------------------------------------------------------

练习:

---------------------------------------------------------------------------------------

总结:

        这是一种树形DP,其特点是每一个父节点都须要对它的各个儿子的属性进行一次DP以求得自己的相关属性。通过一次01背包,把物品转化为几组物品,用分组背包的方法求解。(dfs每一个根结点)

你可能感兴趣的:(问题)