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

01揹包問題

題目

有N件物品和一個容量爲W的揹包。第i件物品的體積是w[i],價值是v[i]。求解將哪些物品裝入揹包可使價值總和最大。

基本思路

特點是:每種物品僅有一件,可以選擇放或不放。

用子問題定義狀態:即dp[i][j]表示前i件物品恰放入一個容量爲j的揹包可以獲得的最大價值。

則其狀態轉移方程便是:

 

01揹包模板代碼:

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

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

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

 我們發現 dp[i][j] 只與 dp[i-1][j] 和  dp[i-1][j-w]有關,也就是當前行的某個值只與前一行的兩個值有關。

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

 

 

01揹包優化後的模板代碼:

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

public int zeroOneKnapsack(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];
}

 

爲什麼空間優化後的01揹包代碼揹包空間要逆序遍歷?(我們來舉一例子)

dp[j]是代表dp[i][j]和dp[i-1][j], 重點在dp[j-w],代表dp[i][j-w]和dp[i-1][j-w]。

在揹包空間順序遍歷的話,若我們要計算dp[j], 由公式dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-w]+v);可知,dp[j](實際是dp[i][j])與dp[i-1][j], dp[i-1][j-w]有關,但是dp[i-1][j-w]實際上已經被dp[i-1][j-w]給覆蓋了。

舉個例子:

N = 4, W = 4

下面爲每個物品的體積和價值:

 

由狀態轉移方程

可得:

 dp[3][4] = max{dp[2][4], dp[2][1]+4}; 注意dp[2][1],如果是順序的話,會被dp[3][1]給覆蓋掉。如果是逆序則不會。

 

推薦:

揹包九講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

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