藉著前面的白話揹包之01揹包的基礎,來結合圖看看完全揹包是個什麼東東,希望以後自己看能一目了然,能對剛接觸的童鞋有幫助是最好不過滴
一:關於完全揹包
有n個物品,每個物品(有無限多個) i 對應有重量w[i]、價值va[i]。有乙個揹包可以放m重的物品,現在讓你從n鐘物品中選擇一些物品,在不超過揹包上限情況使得揹包裝的價值最大。
二:初步了解完全揹包演算法
那麼這裡看看狀態轉移方程:
dp[i][j]=max,理解為在考慮第i件物品的時候,揹包剩餘容量為j下獲得的最大利益。
看看**:解釋清楚再優化
for(int i = 1; i <= n; i ++)
dp[i][j] = max;}}
那麼我們看看這是怎麼運算的,例如,第一件物品w[1] = 3, va[1] = 2;那麼我們對於上面的**,如下圖執行:
那麼先考慮 dp[1][3]的情況,我們發現,在這裡,k迴圈的時候只能取 1,使得dp[1][3] = dp[0][3-1*3]+1*2 = dp[0][0]+2 = 2;意思是,考慮第一件物品,揹包大小為3的情況,我們能放1個第一件物品(多了就放不下啦),使得這個狀態下收益最大。
那麼同理,考慮第一件物品的時候,揹包的其他狀態更新如下:
可以發現,一直到揹包容量為6之前,都只可以放下乙個第一件物品,那麼容量為6的時候,剛好就可以放進兩個
那麼這裡我們就可以發現,其實第一件物品、容量為6的狀態dp[1][6],可以在dp[1][3]的狀態得到,並且其他的狀態也類似。。。
三:那麼我們可以引入優化的一維陣列,同時也降低時間複雜度
先看看一維陣列的演算法:
for(int i = 1; i <= n; i ++)
}
上面說其他狀態類似,到底怎麼類似的呢?,看圖:
那麼,到6之前就變成了
那麼更新 dp[6]的時候,就可以依靠dp[3]+va[1] 得到,那麼在考慮其他的物品的時候,也就類似啦。那麼這裡也就是需要區別01揹包的地方。。。就是for迴圈的時候,是從小到大,因為考慮當前狀態dp[j]的時候,我們是必須依靠前面已有的狀態 (也就是,前面一定放了這件物品,我們再放一件,看能不能得到更大利益) 來更新現在的狀態。
ok,到此完全揹包完畢
個人愚昧觀點,歡迎指正與討論
揹包問題之完全揹包
完全揹包 有n種物品,每種物品有無限個,每個物品的重量為w i 價值為v i 現在有乙個揹包,它所能容納的重量為c,問 你的揹包所能帶走的最大價值是多少?之前01揹包分析過了,如果是順序的話,就表示同一物品可以多次放入!這就是完全揹包!就是這麼神奇!1 include 2 3using namesp...
揹包之01揹包 完全揹包 多重揹包詳解
首先說下動態規劃,動態規劃這東西就和遞迴一樣,只能找區域性關係,若想全部列出來,是很難的,比如漢諾塔。你可以說先把除最後一層的其他所有層都移動到2,再把最後一層移動到3,最後再把其餘的從2移動到3,這是乙個直觀的關係,但是想列舉出來是很難的,也許當層數n 3時還可以模擬下,再大一些就不可能了,所以,...
揹包 01揹包,完全揹包,多重揹包
哈哈 01揹包 f i v max 完全揹包 f i v max 多重揹包 f i v max include include include include include define maxn 1000 using namespace std int n,cap int w maxn 重量 花...