zoukankan      html  css  js  c++  java
  • 01背包和完全背包

    此题之前先分析两种常见的背包问题,01背包与完全背包

    01背包:在M件物品中取出若干件物品放到背包中,每件物品对应的体积v1,v2,v3,....对应的价值为w1,w2,w3,,,,,每件物品之多拿一件。

    解决方案

      考虑用动态规划的方法来解决,这里的:

      阶段是:在前N件物品中,选取若干件物品放入背包中;   状态是:在前N件物品中,选取若干件物品放入所剩空间为W的背包中的所能获得的最大价值;

      决策是:第N件物品放或者不放;  

     

     由此可以写出动态转移方程:

      我们用f[i,j]表示在前 i 件物品中选择若干件放在所剩空间为 j 的背包里所能获得的最大价值

      f[i,j]=max{f[i-1,j-Wi]+Pi (j>=Wi), f[i-1,j]} <1>

      这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c的背包中”,此时能获得的最大价值就是f[v-c]再加上通过放入第i件物品获得的价值w。

    可优化成一维数组的表达式

      for(i=1;i<=m;++i) <2>

      for(v=V;v>=0;v--)

     if(v>=c[i])
    

      f[v]=max{f[v],f[v-c]+w};

    这里一定要注意次序,如果第二个for循环依次增大,则不能与<1>等价,因为f[v],f[v-c]的值不是类似于f[i-1][v],f[i-1][v-c],不信自己可以举例试试,比如2个物品,体积为2,4;价值为1,3;如果顺序,定会出现错误。

    最优解法—O(VN)
    

      for i=1..N

      for j=0..V

      f[j]=max{f[j],f[j-c]+w}

      你会发现,这个伪代码与01背包的伪代码只有v的循环次序不同而已。为什么这样一改就可行呢?

      首先想想为什么01背包中要按照v=V..0的逆序来循环。这是因为要保证第i次循环中的状态f[v]是由状态f[v-c]递推而来。换句话说,这正是为了保证每件物品只选一次,保证在考虑“选入第i件物品”这件策略时,依据的是一个没有已经选入第i件物品的子结果f[v-c]。

      而现在完全背包的特点恰是每种物品可选无限件,所以在考虑“加选一件第i种物品”这种策略时,却正需要一个可能已选入第i种物品的子结果f[v-c],所以就可以并且必须采用v=0..V的顺序循环。这就是这个简单的程序为何成立的道理。

    顺风不浪,逆风不怂。
  • 相关阅读:
    【(高职专科组)第十一届蓝桥杯省模拟赛答案】给定一个数列,请问找出元素之间最大的元素距离。
    【(高职专科组)第十一届蓝桥杯省模拟赛答案】给定一个数列,请问数列中最长的递增序列有多长。
    POJ 2391 二分+最大流
    HDU 4529 状压dp
    NYOJ 747贪心+dp
    NYOJ 745 dp
    HDU 2686 / NYOJ 61 DP
    HDU 4313树形DP
    HDU 4303 树形DP
    POJ 2342 树形DP
  • 原文地址:https://www.cnblogs.com/Stephen-F/p/9877206.html
Copyright © 2011-2022 走看看