揹包九講2——完全揹包問題的理解(Java圖解)

題目

有N種物品和一個容量爲V的揹包,每種物品都有無限件可用。第i種物品的費用是w[i],價值是v[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。

基本思路

這個問題非常類似於01揹包問題,所不同的是每種物品有無限件。也就是從每種物品的角度考慮,與它相關的策略已並非取或不取兩種,而是有取0件、取1件、取2件……等很多種。如果仍然按照解01揹包時的思路,令dp[i][j]表示前i種物品恰放入一個容量爲v的揹包的最大權值。仍然可以按照每種物品不同的策略寫出狀態轉移方程,像這樣:


 

完全揹包的模板代碼:

//N爲物品數量
//W爲揹包總體積
//weights[]爲每個物品的體積
//values[]爲每個物品的價值

public int completeKnapsack(int N, int W, int[] weights, int[] values){
    int[] dp = new int[W+1];

    for(int i = 1; i <= N; i++){
        int w = weights[i-1], v = values[i-1];//每個物品的體積和價值
        for(int j = W; j >= w; j--){ //逆序
            for(int k = 0; k * w <= j; k++){
                dp[j] = Math.max(dp[j], dp[j-k*w]+k*v);
             }
        }
    }
    return dp[W];
}

 

那麼我們只用一維數組記錄,空間優化後的狀態轉移方程:

完全揹包空間優化模板:

//N爲物品數量
//W爲揹包總體積
//weights[]爲每個物品的體積
//values[]爲每個物品的價值

public int completeKnapsack(int N, int W, int[] weights, int[] values){
    int[] dp = new int[W+1];

    for(int i = 1; i <= N; i++){
        int w = weights[i-1], v = values[i-1];//每個物品的體積和價值
        for(int j = w; j <= W; j++){ //順序
            dp[j] = Math.max(dp[j], dp[j-w]+v);
        }
    }
    return dp[W];
}

注意:完全揹包的兩層for循環的次序是可以顛倒的。

如何理解空間優化模板中揹包容量需要順序遍歷(對比01揹包中的逆序遍歷)?

對於轉移方程dp[j] = Math.max(dp[j], dp[j-w]+v), 揹包容量順序遍歷的話,dp[i-1][j-v]會被dp[i][j-v]所覆蓋。所以,

dp[i][j] = Math.max(dp[i-1][j], dp[i][j-w]+v).理解,

特別注意,dp[i][j-w]+v代表着是前i個物品體積爲j-w的最優解,再放入一個第i個物品的最優解。而dp[i][j-w]中可能已經有0, 1, 2, 3...個第i個物品。

 

 

舉個例子:

N = 3, W = 3

 

dp[3][4] = Math.max(dp[2][4], dp[3][3]+2) = 8

總結:

01揹包,揹包容量逆序遍歷,dp[j-w]代表dp[i-1][j-w];

完全揹包,揹包容量順序遍歷,dp[j-w]代表dp[i][j-w];

 

推薦:

揹包九講1——01揹包問題的理解(Java圖解)

https://blog.csdn.net/caigen0001/article/details/106698380

揹包九講2——完全揹包問題的理解(Java圖解)

https://blog.csdn.net/caigen0001/article/details/106711469

揹包九講3——多重揹包問題的理解(Java圖解)

https://blog.csdn.net/caigen0001/article/details/106720118

揹包九講4——二維揹包問題的理解(Java圖解)

https://blog.csdn.net/caigen0001/article/details/106720280

 

 

參考資料:

揹包九講 https://github.com/tianyicui/pack

揹包九講專題 https://www.bilibili.com/video/BV1qt411Z7nE?from=search&seid=6165804124910947817

 

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