完全背包和01背包的比较

问题:在n种物品中选取若干件放在空间为v的背包里,每种物品的体积为c1,c2,…,cn,与之相对应的价值为w1,w2,…,wn.求解怎么装物品可使背包里物品总价值最大

  • 01背包——每种物品只能选0件或者1件
  • 完全背包——每种物品可以选0至多件,没有限制

先放递推关系式子:(dp[ i ] [ j ]表示拿前 i 件物品去塞容积为 j 的背包可以得到的最大价值,所以最后dp[ n ][ v ]就是所求问题的答案)

  • 0—1背包:dp[ i+1 ][ j ] = max ( dp[ i ][ j ], dp[ i ][ j - ci ] + wi )
  • 完全背包:dp[ i+1 ][ j ] = max ( dp[ i ][ j ], dp[ i +1 ][ j - ci ] + wi )

其实0-1背包还是这个式子还是很直观的:(dp最amazing的地方就是找状态转移)。先看一下状态是如何转移的——在从前 i 个往 前 i+1 个选的过程(确定了第 i 个物品的选法,就从 dp[ i ][ ]过渡到了dp[ i+1][ ]),对于第 i 个物品,要么选要么不选,不选的话dp[ i+1 ][ j ]就是dp[ i ][ j ],选的话dp[ i+1 ][ j ]就是 dp[ i ][ j - ci ] + wi  (为啥是 j-ci ? 因为状态是从j-ci 加上放入的第 i 个物品 ci 才到 j的嘛  )。最后选的当然是两者的max。

上面给的完全背包的式子就比较抽象了。在理解完全背包的dp[ i+1 ][ j ] = max ( dp[ i ][ j ], dp[ i +1 ][ j - ci ] + wi )之前,我们先来铺垫完全背包的另一种写法的式子:

dp[ i+1][ j ] = max{ dp[ i ][ j - k*ci]+k* wi}

因为完全背包中,第 i 个物品可以选多次,上式中的 k 就代表了这个次数。 由于上式左边背包最大容积为 j ,所以 k 最大最大不能超过 j / ci; 故 k 的范围是 0<= k <= j/ci;

这个式子是很直观的,甚至0-1背包也可以用这个式子表示,只要把 k 的取值范围改成只有0和1,k={0,1}。也就是说,其实0-1背包就是一种特殊的完全背包。 虽然得出这个结论不难,但是如果单单只看开始给出的那两个递推关系式,我们是无法直观地看出结论的。

既然这个式子这么直观,干嘛不直接用它呢?原因就是它效率不高,因为做了很多重复工作——细想一下我们就会发现,其实在计算dp[ i+1 ][ j ]时计算的dp[ i ][ j - k*ci]+k* wi (k>=0) 的k>=1部分 和 计算 dp[ i+1][ j-wi]时就算的dp[ i ][ j - k*ci]+k* wi (k>=0)做的工作时一模一样的。

(即在计算dp[i+1][ j ]中选择m(m>=1)个 第i个物品 和计算 dp[ i+1][ j-ci]时选择 m-1个第i个物品是一样样的)

现在来证明为什么max ( dp[ i ][ j ] , dp[ i +1 ][ j - ci ] + wi )max{ dp[ i ][ j - k*ci]+k* wi}是等价的。

dp[ i+1][ j ]=max( dp[ i ][ j ] , dp[ i+1 ][ j - ci ]+wi  )

                =max (dp[ i ][ j ] , max { dp[ i ][ j- ci - k * ci ]+k *wi } +wi ),  k>=0

                =max ( dp[ i ][ j ] , max{  dp[ i ][ j- k * ci ]+k *wi }),  k>=1

               =max{  dp[ i ][ j- k * ci ]+k *wi },k>=0

猜你喜欢

转载自www.cnblogs.com/moderateisbest/p/9465717.html