(1)0/1揹包
for i:=1 to n do
for j:=vtot downto v[i] do
f[j]:=max(f[j-v[i]]+w[i],f[j]);
如果題目要求恰好裝滿揹包,則f陣列除了f[0]初始化為0之外,其他的初始化為-maxlongint;
(2)完全揹包(每個物品有無限件可用)
for i:=1 to n do
for j:=v[i] to vtot do
f[j]:=max(f[j],f[j-v[i]]+w[i]);
(3)多重揹包(每個物品有有限件可以用)
porocedure init;
var
x,y,z,i:longint;
begin
readln(x,y,z);
i:=1;
while ibegin
inc(tt);
v[tt]:=x*i;
w[tt]:=y*i;
dec(z,i);
i:=i*2;
end;
inc(tt);
v[tt]:=x*z;
w[tt]:=y*z;
end;
01揹包
(4)混合揹包
對所有多重揹包拆分
for i:=1 to n do
if 當前物品是01揹包……
if 當前物品是完全揹包……
(5)多維費用揹包
在方程上加一維即可
方法同上
這裡不再寫
物品總個數的限制
有時,「二維費用」的條件是以這樣一種隱含的方式給出的:最多只能取m件物品。這事實上相當於每件物品多了一種「件數」的費用,每個物品的件數費用均為1,可以付出的最大件數費用為m。換句話說,設f[v][m]表示付出費用v、最多選m件時可得到的最大價值,則根據物品的型別(01、完全、多重)用不同的方法迴圈更新,最後在f[0..v][0..m]範圍內尋找答案。注:只要是01揹包,不管幾維都要倒序迴圈
(6) 分組揹包
for 所有的組k
for v=v..0
for 所有的i屬於組k
f[v]=max
注意這裡的三層迴圈的順序, 「for v=v..0」這一層迴圈必須在「for 所有的i屬於組k」之外。這樣才能保證每一組內的物品最多只有乙個會被新增到揹包中。
(7)求方案總數
對於這類改變問法的問題,一般只需將狀態轉移方程中的max改成sum即可。例如若每件物品均是完全揹包中的物品,轉移方程即為
f[i][v]=sum
初始條件f[0][0]=1。
(8)求最優方案總數
這裡的最優方案是指物品總價值最大的方案。以01揹包為例。
結合求最大總價值和方案總數兩個問題的思路,最優方案的總數可以這樣求:f[i][v]意義同前述,g[i][v]表示這個子問題的最優方案的總數,則在求f[i][v]的同時求g[i][v]的偽**如下:
for i=1..n
for v=0..v
f[i][v]=max
g[i][v]=0
if(f[i][v]==f[i-1][v])
inc(g[i][v],g[i-1][v])
if(f[i][v]==f[i-1][v-c[i]]+w[i])
inc(g[i][v],g[i-1][v-c[i]])
我發現揹包這個東西真的是好強大,和以前看的感覺完全不一樣,今天先寫到這裡吧,明天我會繼續寫的。
加油!
演算法學習筆記4 動態規劃 揹包問題
其實動態規劃特別抽象,特別難講。這裡也可以參考一篇博文,用講故事的方式講了出來。通過金礦模型介紹動態規劃 我的理解就是 用更多的問題來回答問題 動態規劃是一種求解最優化問題的方法,因為它沒有乙個確定的數學表示式,或者是明確的解題步驟,說起來會比較抽象,我們只能在實際題目中體會。首先說幾個概念吧 這裡...
動態規劃 揹包問題筆記
理解動態規劃先從 通過金礦模型介紹動態規劃 之後,可以通過下面部落格的表來理解 動態規劃之01揹包問題 最易理解的講解 程式實現時,思路和畫表時相同 給出程式 coding utf 8 n為物品數量 c為揹包重量 w為每個物品重量 v為每個物品價值 def bag n,c,w,v res 1 for...
動態規劃學習 0 1揹包問題,學習筆記
下面給出問題描述 有乙個揹包,它的容量為c capacity 現有n種不同的物品,編號為0 n 1,其中每一件物品的重量為w i 價值為v i 問可以向這個揹包中盛放哪些物品,使得在不超過揹包容量的基礎上,物品的總價值最大。如果使用暴力解法,則每一件物品都可以放進揹包也可以不放進揹包,其時間複雜度為...