對0 1揹包問題的理解

2021-06-19 16:30:43 字數 1644 閱讀 2841

首先宣告的是這是一篇非常非常基礎的對0-1揹包問題的理解。

這兩天看了動態規劃初步,看到了0-1揹包問題。看到這裡的時候感覺理解有點困難。

問題簡介:有乙個體積為c的揹包,要往裡面裝n中物品,第i種物品的體積為vi,質量為wi,求出揹包裡面最多能裝下多重的物品。

劉汝佳對這個問題的分析是引用了前面的回朔法來理解,但是我覺得這種理解的方法還是有些抽象。

他給出了乙個狀態轉移方程,d(i,j)=max。d(i,j)的意義是在第i層剩餘體積為j 時的最大重量。因為是回朔法,所以答案就應當是d(i,j)。

**如下:(d[n+1][ ]這些元素所有的值都是0)

for(int i = n ; i >= 1; i--)

for(int j = 0; j <= c; ++j)

剛開始的時候對這個**以及他的狀態轉移方程都不是很理解。參考一下前面的硬幣問題。

硬幣問題簡介:有n中面值的硬幣,現在要用他們來表示s元錢,求使用的硬幣最多的數量以及最少的數量。

這裡,很容易列出狀態轉移方程(以最少為例),money[i]=min。理解起來也很簡單,money[i]表示的是當錢幣總和為i 時,使用的最少的錢幣數量。v[i]的含義就是第[i]種錢幣的面值。當錢幣的總和為i 時,使用的錢幣數量最小值就是當前已經得到的最小值與從總面值為i-vi到i的錢幣數量的最小值中更小的那個。

**如下:

for(int i=1;i<=s;i++)

min[i]=inf;

for(int i=1;i<=s;++i)//s是要達到的總和

for(int j=1;j<=n;++j)//n是錢幣面值的種類

if(i>v[i])min[i] = min[i] < (min[i-v[j]]+1) ? min[i] : min[i-v[j]]+1 ;

這樣,利用狀態轉移方程就列出了乙個遞推關係式。我們並不關心是如何達到 i-vi 這個總和的,我們只需要知道從 i-vi 到 i 需要增加乙個硬幣即可。

回過頭來看現在面臨的0-1揹包問題。為什麼這個問題會使用有兩個引數的狀態轉移方程呢?在硬幣問題中,每種硬幣的數量是可以無限增加的,但是在揹包問題中,每個物品的數量卻只有乙個。這就造成了兩個問題的細微差別。

現在用這種方式來理解揹包問題,d(i,j)表示從 i+1 個物品中選擇乙個出來使體積達到 j 的時候重量的最大值(有點繞)。

從**中看出,取物品的順序給限定了(for(int i=n;i>=1;--i)),表示是從最後乙個物品開始取,乙個乙個地放進揹包,這樣就使得取的物品不會重複。陣列的第二維就表示目前揹包中已經有的體積(跟硬幣問題一樣,我們並不關心是怎麼樣到達這個體積的,我們只關心從體積 i-v[i] 到i 會增加的重量是 w[i])。

在後面又介紹了另一種用於揹包問題的方法,是這種方法「對稱」的方法。感覺用我的那種理解方法的話,這種方法更得當

for(int i = 1;i<=n;++i)

for(int j=0;j<=c;++j)

發現了嗎?這裡跟上面的**不同之處就是外層迴圈的順序變了。在這裡,放物品的順序就是從第1個開始往裡面放,一直放到最後乙個。所以,最終的答案也就是f(n,c)

01揹包問題的理解

01揹包是 n個物品重量和價值分別為w i v i 揹包可以容納的重量為weight,怎麼裝下最大價值的物品?狀態轉移方程是 value i,w max value i 1,w w i v i value i 1,w 要求w的解,那麼先求w w i 的解,w w i 的值只有在知道了i是多少時才知道...

揹包01問題初理解

揹包問題 knapsack problem 是一種組合優化的np完全問題。問題可以描述為 給定一組物品,每種物品都有自己的重量和 在限定的總重量內,我們如何選擇,才能使得物品的總 最高。問題的名稱 於如何選擇最合適的物品放置於給定揹包中。具體理解可以直接通過下面的例子來理解揹包問題 揹包問題的乙個例...

01揹包問題深度理解

有n件物品和乙個容量為v的揹包,求可以得到的最大價值。其中重量是w i 價值是v i 例 4 5 1 22 3 3 42 2 01揹包問題的常用的f v max f v f v w i v i 的解法是由樹遞迴得來的,這裡從頭推演一遍。我們可以這樣理解,從第乙個物品開始,每個物品都有兩種情況 選或不...