動態規劃 01揹包問題滾動陣列 一維陣列

2021-09-25 08:12:46 字數 1177 閱讀 5875

看了好幾天的揹包問題。。。終於有了一點淺顯的理解

一開始學完01揹包的二維寫法,再看一維寫法是一臉懵逼的,自己推導了幾遍過程,終於是理解了!!!分享一下蒟蒻的心得

問題如下:有n個重量和價值分別為wi,vi的物品。從這些物品中挑選出總重量不超過w的物品,求所有挑選方案中價值總和的最大值。

輸入:n=4 (w,v)=

輸出:7

最大負重為5

如果學過01揹包的二維陣列寫法,那麼應該會發現若是遞推順序是正序,那麼我們需要用到的是左上方和正上方的資料,如下圖

當計算dp[i+1]時,dp[i-1]的部分就用不到了。

那麼用一維陣列又是怎麼做的?我們是把上面講過的左上方和正上方的部分結合起來,從後往前推導

從第乙個物品開始,在前面更新的陣列基礎上繼續去更新dp陣列的內容,直到沒有物品為止。

核心**如下:

for (int i = 0; i < 4; i++) {

for (int j = bag_w; j >=w[i]; j--)

dp[j] = max(dp[j], dp[j - w[i]] + v[i]);

bag_w為重量上限

推導過程如下:

dp右邊是一維陣列下標

舉個例子,在列舉完i=0的情況時,i=1時使用的是上一次更新完的陣列,

dp[j]=max(dp[j],dp[j-w[1]]);等號右邊的dp[j]是上一次更新的,即使一維陣列裡面的dp[j],dp[j-w[1]]相當於二維陣列的dp[i-1][j],dp[i-1][j-w[1]],這樣,我們就把二維陣列進行了降維。

比如說數塔問題,就是一行一行地去更新,也就是在一維陣列裡面不斷滾動

可以試著去推導,如果是正序的話,同乙個物品可能會多次使用,

例如,i=0時,dp[2]=3,dp[3]=3,dp[4]=6,注意了,這裡dp[4]=max(dp[4],dp[4-w[0]+v[0])=6;可以看到,在dp[2]的基礎上,又放入了物品1,這就變成了完全揹包而不是01揹包了。

切記,一維必須是逆序的,而二維可以正序也可以逆序。

動態規劃揹包問題 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的情況下,最...