1. 程式人生 > 其它 >DP---01揹包問題

DP---01揹包問題

  揹包的最大容積為:8

  dp[i][j]表示將前i件物品裝進限重為j的揹包可以獲得的最大價值。
注:j表示的是當前揹包的容積,即它還能容納多少東西,而不是當前揹包中物品的總體積。所以,隨著物品的加入,j會減小,及容積減小。

轉移狀態方程:

  dp[i][j]=dp[i-1][j-w[i]]+v[i]的理解:

  這種情況下,狀態i是由狀態i-1加了第i件物品得到的,那麼體現出來就是,i-1狀態時的揹包容積減去第i件物品的體積即j-w[i]構成了狀態i時的揹包的總容積,(因為把第i件物品加進去了。揹包的總容積要變小)。

  而總價值就是要加上第i件物品的價值,即i-1狀態時的總價值加上第i件物品的價值(+v[i]),構成了狀態i時揹包的總價值。

(1)

w[],v[]兩個陣列傳入函式前未做處理
  //w[],v[]兩個陣列傳入函式前未做處理
        int[] w={2,3,4,5};
        int[] v={3,4,5,6};
        int m=8;
 1  //w[],v[]兩個陣列傳入函式前未做處理
 2     public static int findMaxValue(int[] w,int[] v,int m ){
 3 
 4         int line=w.length;
 5         int row=m;
 6 
 7         int[][] dp=new int
[line+1][row+1]; 8 9 10 for(int i=1;i<line+1;i++){ 11 for(int j=1;j<row+1;j++){ 12 if(j<w[i-1]){ 13 dp[i][j]=dp[i-1][j]; 14 }else{ 15 dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-w[i-1]]+v[i-1]);
16 } 17 } 18 } 19 20 return dp[line][row]; 21 22 }

空間優化:

 1 //滾動陣列,優化空間
 2     //w[],v[]兩個陣列傳入函式前,均已經在第一位添加了0
 3     public static int findMaxValue3(int[] w,int[] v,int m){
 4         int[] dp=new int[m+1];
 5         for(int i=0;i<w.length;i++){
 6             for(int j=m;j>=w[i];j--){
 7                 dp[j]=Math.max(dp[j],dp[j-w[i]]+v[i]);
 8             }
 9         }
10         return dp[m];
11 
12     }

(2)

w[],v[]兩個陣列傳入函式前,均已經在第一位添加了0
1 //w[],v[]兩個陣列傳入函式前,均已經在第一位添加了0
2         int[] w1={0,2,3,4,5};
3         int[] v1={0,3,4,5,6};
4         int m1=8;
 1 //w[],v[]兩個陣列傳入函式前,均已經在第一位添加了0
 2     public static int findMaxValue1(int[] w,int[] v,int m ){
 3 
 4         int line=w.length;
 5         int row=m+1;
 6 
 7         int[][] dp=new int[line][row];
 8 
 9         for(int i=1;i<line;i++){
10             for(int j=1;j<row;j++){
11                 if(j<w[i]){
12                     dp[i][j]=dp[i-1][j];
13                 }else{
14                     dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
15                 }
16             }
17         }
18 
19         return dp[line-1][row-1];
20 
21     }

空間優化:

 1 //滾動陣列,優化空間
 2     //w[],v[]兩個陣列傳入函式前,均已經在第一位添加了0
 3     public static int findMaxValue3(int[] w,int[] v,int m){
 4         int[] dp=new int[m+1];
 5         for(int i=0;i<w.length;i++){
 6             for(int j=m;j>=w[i];j--){
 7                 dp[j]=Math.max(dp[j],dp[j-w[i]]+v[i]);
 8             }
 9         }
10         return dp[m];
11 
12     }