關於揹包問題,其實可以分為兩種型別:0-1揹包問題(動態規劃) 和 部分揹包問題(貪心演算法)。
在選擇是否要把乙個物品加到揹包中,必須把該物品加進去的子問題的解與不取該物品的子問題的解進行比較。這種方式形成的問題導致了許多重疊子問題,滿足動態規劃的特徵。
總是選擇每一磅價值 (vi / wi) 最大的物品新增進揹包中。那麼其解決過程是:對每磅價值進行排序,依次從大到小選擇新增進揹包中。
更通俗點理解,0-1揹包問題的一件物品可以想象成是乙個金錠;而部分揹包問題中的一件物品可以想象成是金粉。假設山洞裡共有a, b, c, d, e這5件寶物(不是5種寶物),它們的重量分別是2,2,6,5,4,它們的價值分別是6,3,5,4,6,現在給你個承重為10的揹包, 怎麼裝揹包,可以才能帶走最多的財富。
有編號分別為a,b,c,d,e的五件物品,它們的重量分別是2,2,6,5,4,它們的價值分別是6,3,5,4,6,現在給你個承重為10的揹包,如何讓揹包裡裝入的物品具有最大的價值總和?
name
weight
value12
3456
78910
a260
6699
1212
151515b
2303
3669
991011c6
5000
6666
61011d
5400
0666
661010e4
6000
6666
666只要你能通過找規律手工填寫出上面這張表就算理解了01揹包的動態規劃演算法。
首先要明確這張表是至底向上,從左到右生成的。
講解1:
為了敘述方便,用e2單元格表示e行2列的單元格,這個單元格的意義是用來表示只有物品e時,有個承重為2的揹包,那麼這個揹包的最大價值是0,因為e物品的重量是4,揹包裝不了。
對於d2單元格,表示只有物品e,d時,承重為2的揹包,所能裝入的最大價值,仍然是0,因為物品e,d都不是這個揹包能裝的。
同理,c2=0,b2=3,a2=6。
講解2:
對於承重為8的揹包,a8=15,是怎麼得出的呢?
根據01揹包的狀態轉換方程,需要考察兩個值,乙個是f[i-1,j],對於這個例子來說就是b8的值9,另乙個是f[i-1, j-wi]+pi;
在這裡,f[i-1, j]表示我有乙個承重為8的揹包,當只有物品b,c,d,e四件可選時,這個揹包能裝入的最大價值。
f[i-1, j-wi]表示我有乙個承重為6的揹包(等於當前揹包承重減去物品a的重量),當只有物品b,c,d,e四件可選時,這個揹包能裝入的最大價值。
f[i-1, j-wi]就是指單元格b6,值為9,pi指的是a物品的價值,即6。
由於f[i−1,j−wi]+pi=9+6=15f[i−1,j−wi]+pi=9+6=15 大於f[i−1,j]=9f[i−1,j]=9,所以物品a應該放入承重為8的揹包。
f[i−1,j−wi]+vif[i−1,j−wi]+vi 是選擇vivi這件物品時,能夠產生的最大價值,而f[i-1, j-wi] 表示上乙個最優狀態,j−wij−wi是上乙個最優狀態時的揹包容量。0-1揹包問題子結構:選擇乙個給定物品i,則需要 比較(選擇 i 的形成的子問題的最優解) 與 (不選擇 i 的子問題的最優解)。分成兩個子問題,進行選擇比較,選擇最優的。
0-1揹包問題遞迴過程:設有n個物品,揹包的重量為w,c[i][w]為最優解。即:
下面給出偽**實現:
通過上面的偽**,我們會發現,實現的過程有點羅嗦,下面給出乙個簡約點的實現,思路都是一樣的。
偽**:
最優值:求解整個揹包最後的總價值達到最優。求解揹包問題的最優值,關鍵是要弄清楚上面的遞推式子。
最優解:當揹包價值達到最大時,列出所選取的物品都是那些。
**的實現過程是這樣的:
int remainspace = w;
//輸出所選擇的物品列表:
for(int i=n; i>=1; i--)
} }
完全揹包問題講解(dp)
此題之前先分析兩種常見的揹包問題,01揹包與完全揹包 01揹包 在m件物品中取出若干件物品放到揹包中,每件物品對應的體積v1,v2,v3,對應的價值為w1,w2,w3,每件物品之多拿一件。解決方案 考慮用動態規劃的方法來解決,這裡的 階段是 在前n件物品中,選取若干件物品放入揹包中 狀態是 在前n件...
最清楚的01揹包問題講解
題目 01揹包問題描述 有編號分別為a,b,c,d,e的n 5件物品,它們的重量w分別是2,2,6,5,4,它們的價值v分別是6,3,5,4,6,每件物品數量只有乙個,現在給你個承重為m 10的揹包,如何讓揹包裡裝入的物品具有最大的價值總和sum v?在dp dynamic programming,...
揹包問題 01揹包問題
n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...