1. 程式人生 > >01揹包問題總結

01揹包問題總結

在n個物品中挑選若干物品裝入揹包,最多能裝多滿?假設揹包的大小為m,每個物品的大小為A[i]

樣例

如果有4個物品[2, 3, 5, 7]

如果揹包的大小為11,可以選擇[2, 3, 5]裝入揹包,最多可以裝滿10的空間。

如果揹包的大小為12,可以選擇[2, 3, 7]裝入揹包,最多可以裝滿12的空間。

函式需要返回最多能裝滿的空間大小。

思路:動態規劃做法,找出狀態轉移方程,在 本題中,我用dp[i][j]表示  揹包剩餘容量為j時,考慮前1到j件物品的最優解(即容量為j時,前1到i件物品中能拿的最大重量)

此時有兩種選擇,當第i件物品的重量小於等於j時,則有拿和不拿兩種選擇,這時最優解為:

if (A[i-1] <= j) {
       dp[i][j]=Math.max(dp[i-1][j-A[i-1]]+A[i-1],dp[i-1][j]);
 }

當第i件物品重量大於j時,則第i件物品肯定拿不了,這時

dp[i][j]=dp[i-1][j];

到這裡狀態轉移方程已經找出來了。總的程式碼如下:

public class Solution {
    //dp[i][j]陣列表示前i件物品在揹包容量為j時能拿的最大容量
    int [][]dp;
    public int backPack(int m, int[] A) {
        //c表示物品總數量
        int c=A.length;
        dp=new int[c+1][m+1];
        for(int i=1;i<=c;i++){
            for(int j=1;j<=m;j++){
                if(A[i-1]<=j){
                    dp[i][j]=Math.max(dp[i-1][j-A[i-1]]+A[i-1],dp[i-1][j]);
                }else{
                    dp[i][j]=dp[i-1][j];
                }
            }
        }
        return dp[c][m];
    }
}

這樣dp[c][m]即為當揹包容量為m時c件物品能拿的最大容量,即題目所求了。

未完待續。。。。