• 背包问题


     

    一、01背包问题

    最基础的背包问题:有N件物品和一个容量为V的背包。第i件物品的体积是w[i],价值是v[i]。求解将哪些物品装入背包可使物品的总价值达到最大。

    我们用dp[i][j]表示在总体积不超过j的情况下,前i个物品所能达到的最大价值。初始时,dp[0][j]为0。

    依据每种物品是否被放入背包,每个状态有两个状态转移的来源。

    1.若物品i被放入背包,设其体积为w,价值为v,则dp[i][j] = dp[i-1][j-w]+v。

    2.若物品不放入背包,则dp[i][j] = dp[i-1][j]。

    选择两者之中的较大值成为状态dp[i][j]的值。 即状态转移方程:dp[i][j] = max{ dp[i-1][j], dp[i-1][j-w]+v};

    同时注意:j-w的值是否为非负值,若为负值则该状态来源不能被转移。

     1 // 状态转移
      for(int i=1; i<=m; i++) 2 {//循环每一个物品 3 4 for(int j=t; j>=list[i].w; j--) 5 { 6 dp[i][j]=max(dp[i-1][j], dp[i-1][j-list[i].w]+list[i].v); 7 } 8 //j属于list[i].w-1~0 9 for(int j=list[i].w-1; j>=0; j--) 10 { 11 dp[i][j]=dp[i-1][j]; 12 } 13 }

    观察状态转移的特点,我们发现dp[i][j]的转移仅与dp[i-1][j-list[i].w]和dp[i-1][j]有关,即仅与二维数组中本行的上一行有关。根据这个特点,我们可以将原本的二维优化。

    dp[j] = max{ dp[j], dp[j-list[i].w]+v };

     1   // 状态转移 (简化后)
     2   for(int i=1; i<=m; i++)
     3           {//循环每一个物品
     4   
     5               for(int j=t; j>=list[i].w; j--)
     6               {
     7                   dp[j]=max(dp[j], dp[j-list[i].w]+list[i].v);
     8               }
     9              
    10           }

    在0-1背包中,之所以逆序循环更新状态是为了保证更新dp[j]时,dp[j-list[i].w]的状态尚未因为本次更新而发生变化。因此必须逆序更新每个dp[j]的值。

    0-1背包存在一个简单的变化:即要求所选择的物品必须恰好装满背包。此时,只需要改变初始状态,dp[0][0]为0,而其他dp[0][j]值均变化为负无穷或者是不存在。该变化与原始的0-1背包的差别只体现在初始值方面。

    二、完全背包

    完全背包是在0-1背包的基础上,使每种物品的数量无限增加。

    完全背包:有一个体积为V的背包,同时又n个物品,每个物品均有各自的体积w和价值v,每个物品的数量均为无限个,求使用该背包最多能装的物品价值总和。

    简单来说,使用之前空间优化过的一维数组来解,按如下方法转移:

     1   // 状态转移 (简化后)
     2   for(int i=1; i<=m; i++)
     3           {//循环每一个物品
     4   
     5               for(int j=list[i].w; j<=t; j++)
     6               {
     7                   dp[j]=max(dp[j], dp[j-list[i].w]+list[i].v);
     8               }
     9              
    10           }

    与0-1背包相比,似乎只存在着对状态j的遍历顺序有所差异。这是因为0-1背包中每个物品至多只能被选择一次。而在完全背包中,每个物品可以被选择无限次,那么状态dp[i][j]恰好可以由可能已经放入物品i的状态转移而来。

    总结一下:完全背包解法与0-1背包整体保持一致。不同的只是状态更新时的遍历顺序。

  • 相关阅读:
    Yii隐藏单入口
    JS字符串的问题
    暑假第三测
    暑假第二测
    暑假第一测
    沈阳集训day4
    沈阳集训day3
    P2571 [SCOI2010]传送带
    CF626C Block Towers
    洛谷P4171 [JSOI2010]满汉全席
  • 原文地址:https://www.cnblogs.com/shenckicc/p/6806209.html
Copyright © 2020-2023  润新知