演算法 動態規劃0 1揹包問題

2021-09-26 08:58:13 字數 1923 閱讀 5474

有乙個容量為 n 的揹包,要用這個揹包裝下物品的價值最大,這些物品有兩個屬性:體積 w 和價值 v。

定義乙個二維陣列 dp 儲存最大價值,其中 dp[i][j] 表示前 i 件物品體積不超過 j 的情況下能達到的最大價值。設第 i 件物品體積為 w,價值為 v,根據第 i 件物品是否新增到揹包中,可以分兩種情況討論:

第 i 件物品可新增也可以不新增,取決於哪種情況下最大價值更大。因此,0-1 揹包的狀態轉移方程為:

// w 為揹包總體積

// n 為物品數量

// weights 陣列儲存 n 個物品的重量

// values 陣列儲存 n 個物品的價值

public

intknapsack

(int w,

int n,

int[

] weights,

int[

] values)

else}}

return dp[n]

[w];

}

在程式實現時可以對 0-1 揹包做優化。觀察狀態轉移方程可以知道,前 i 件物品的狀態僅與前 i-1 件物品的狀態有關,因此可以將 dp 定義為一維陣列,其中 dp[j] 既可以表示 dp[i-1][j] 也可以表示 dp[i][j]。此時,

因為 dp[j-w] 表示 dp[i-1][j-w],因此不能先求 dp[i][j-w],防止將 dp[i-1][j-w] 覆蓋。也就是說要**先計算 dp[i][j] 再計算 dp[i][j-w],**在程式實現時需要按倒序來迴圈求解。

j是從w降到 1 ,而不是從1公升到w,特別注意!!!

public

intknapsack

(int w,

int n,

int[

] weights,

int[

] values)

/* j}

}return dp[w]

;}

leetcode題:將陣列劃分為相等兩部分

可以看成乙個揹包大小為 sum/2 的 0-1 揹包問題。

class

solution

if(sum %2!=

0)return

false

;int w= sum /2;

//0-1揹包問題

boolean

dp =

newboolean

[w+1];

dp[0]

=true

;//注意,

for(

int i =

1;i<=n;i++)}

}return dp[w];}

}

(1)迴圈還可以改進:

將i = 1 ~n , 改為for(int i :nums)

//0-1揹包問題

boolean

dp =

newboolean

[w+1];

dp[0]

=true

;//注意,

for(

int i :nums)}}

return dp[w]

;

(2)還可以再改進??由上迴圈可發現,j boolean

dp =

newboolean

[w+1];

dp[0]

=true

;//注意,

for(

int i :nums)

}return dp[w]

;

動態規劃揹包問題 01揹包

問題描述 n種物品,每種乙個。第i種物品的體積為vi,重量為wi。選一些物品裝到容量為c的揹包,使得揹包內物品不超過c的前提下,重量最大。問題分析 宣告乙個f n c 的陣列。f i j 表示把前i件物品都裝到容量為j的揹包所獲得的最大重量。當 j v i 時,揹包容量不足以放下第 i 件物品,f ...

動態規劃 揹包問題 01揹包

有n種物品和乙個容量為v的揹包,每種物品僅用一次。第i件物品的費用是w i 價值是v i 求解將哪些物品裝入揹包可使價值總和最大。例如 n 5,v 10 重量 價值 第乙個物品 10 5 第二個物品 1 4 第三個物品 2 3 第四個物品 3 2 第五個物品 4 1 首先我們考慮貪心策略,選取最大價...

0 1揹包問題(動態規劃)

一 問題描述 有n件物品和乙個容量為v的揹包。第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。所謂01揹包,表示每乙個物品只有乙個,要麼裝入,要麼不裝入。二 解決方案 考慮使用動態規劃求解,定義乙個遞迴式 opt i v 表示前i個物品,在揹包容量大小為v的情況下,最...