筆記 演算法學習 動態規劃 揹包問題總結(1)

2022-07-21 00:09:23 字數 1750 閱讀 2371

(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 問可以向這個揹包中盛放哪些物品,使得在不超過揹包容量的基礎上,物品的總價值最大。如果使用暴力解法,則每一件物品都可以放進揹包也可以不放進揹包,其時間複雜度為...