DP---01揹包問題
阿新 • • 發佈:2021-06-28
揹包的最大容積為: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 }