動態規劃(二)完全揹包問題

       在上一篇文章中,簡單分析了0-1揹包問題,這篇接着簡單分析下完全揹包問題。

        完全揹包的問題形式如下:有一揹包,只能裝重量爲V的物品,有n個的物品,這些物體體積爲w,價值爲v,在每個物品最多可以裝無線個的情況下,怎麼裝物品可以讓揹包中的物品價值最大。完全揹包問題與0-1揹包相似,不同的是:0-1揹包問題彙總,每個物品最多隻能裝1個;而在完全揹包中,每個物品在不超過揹包限重的情況下,可以裝無數個。因此,完全揹包的分析思路與0-1揹包類似,不同之處在於狀態轉移公式的推導。

       與0-1揹包問題分析類似,可以先定義一些變量,來輔助分析。具體爲:value[ i ]表示第i個物品的價值,weight[ i ]表示第i個物品的體積,dp[ j ]表示當前揹包容量爲j時,最佳組合對應的價值。爲方便分析,設定物品個數爲5,揹包重量限制爲20,示例數據如下:

體積(weight) 2 3 4 5 9
價值(value) 3 4 5 8 10

        分析步驟如下:

           1、如果按照上篇文章的方式做,構建一個二維數組,就需要三層for循環,肯定不是一個好的解決方法。此時可以用一維數組dp[ ]直接來存儲value,進而用兩層for循環解決該問題。

           2、以dp[ j ],即揹包可裝重量爲j的狀態來進行分析(i爲物品種類)。此時可能進行的動作有如下幾種:

                  1>再裝入一件相同物品價值大,即dp[ j ] = dp[ j+1 ];

                  2>再裝入一件其他物品價值大,即dp[ j ] = dp[ j-weight[ i ] ] + value[ i ]。

      尋找最大價值的過程,就是不斷更新dp數組的過程,直到數組中最後一個值填完,即最大value值。

     Java代碼如下:

           static int weight[ ]={0,2,3,4,5,9};       //每個商品容量
           static int value[ ]={0,3,4,5,8,10};       //每個商品價值
           static int NUM = weight.length;         //商品種類。包含第0個這個特殊值
           static int CAP = 21;                           //總可用容量+1,包含第0個這個特殊值,所以總容量是20

            

           //不斷填充value數組
           int dp[] = new int[ CAP ];
           for(int i=1;i<NUM;i++){
                for(int j=weight[ i ];j<CAP;j++){
                    dp[ j ] = Math.max(dp[ j ],dp[ j-weight[ i ] ]+value[ i ]);
                }
           }

 

         //數組最後一個值,即爲最大value值
         System.out.println(dp[ 20 ]);

                

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章