完全揹包詳解

2021-08-15 15:27:22 字數 1038 閱讀 8667

背景:有n種物品和乙個容量為v的揹包,

每種物品都有無限件可用。第i種物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。

我們注意看紅字部分,完全揹包與01揹包的不同之處在於每件物品有無限個,故而對於完全揹包策略要從

選與不選轉變為

選幾件(0,1,2,.....)的問題

如果依然按照解01揹包的思路,那我們獲得的狀態轉移方程:

f[i][v]=max

雖然總共的求解狀態還是v*n個,但是每個求解狀態的

時間複雜度已經不是常數級別了。

故而我們要加以改進他

既然01揹包問題是最基本的揹包問題,那麼我們可以考慮把完全揹包問題轉化為01揹包問題來解。最簡單的想法是,考慮到第i種物品最多選v/c [i]件,於是可以把第i種物品轉化為v/c[i]件費用及價值均不變的物品,然後求解這個01揹包問題。這樣完全沒有改進基本思路的時間複雜度,但這畢竟給了我們將完全揹包問題轉化為01揹包問題的思路:將一種物品拆成多件物品。

更高效的轉化方法是:把第i種物品拆成費用為c[i]*2^k、價值為w[i]*2^k的若干件物品,其中k滿足c[i]*2^k

* o(vn)的演算法 :

這個演算法使用一維陣列,先看偽**: 

for i=1..n 

for v=0..v

f[v]=max;

你會發現,這個偽**與01的偽**只有v的迴圈次序不同而已。為什麼這樣一改就可行呢?

首先想想為什麼01中要按照v=v..0的逆序來迴圈。這是因為要保證第i次迴圈中的狀態f[i][v]是由狀態f[i-1][v-c[i]]遞推而來。換句話說,這正是為了保證每件物品只選一次,保證在考慮「選入第i件物品」這件策略時,依據的是乙個絕無已經選入第i件物品的子結果f[i-1][v-c[i]]。而現在完全揹包的特點恰是每種物品可選無限件,所以在考慮「加選一件第i種物品」這種策略時,卻正需要乙個可能已選入第i種物品的子結果f[i][v-c[i]],所以就可以並且必須採用v= 0..v的順序迴圈。這就是這個簡單的程式為何成立的道理。

完全揹包詳解

揹包問題是動態規劃裡面很重要的一部分,徹底理解各種揹包問題,對動態規劃的後續學習有很大的幫助.更全的揹包問題,可參看 揹包九講 學會了0 1揹包後,多重揹包 完全揹包就比較容易理解.一.什麼是 完全揹包 有這樣乙個問題 在你面前放著n種寶石,每種寶石重量為wi,價值為vi,數量無限 你有乙個最多可以...

01揹包,完全揹包,多重揹包詳解

揹包之01揹包 完全揹包 多重揹包詳解 ps 大家覺得寫得還過得去,就幫我把部落格頂一下,謝謝。首先說下動態規劃,動態規劃這東西就和遞迴一樣,只能找區域性關係,若想全部列出來,是很難的,比如漢諾塔。你可以說先把除最後一層的其他所有層都移動到2,再把最後一層移動到3,最後再把其餘的從2移動到3,這是乙...

揹包之01揹包 完全揹包 多重揹包詳解

首先說下動態規劃,動態規劃這東西就和遞迴一樣,只能找區域性關係,若想全部列出來,是很難的,比如漢諾塔。你可以說先把除最後一層的其他所有層都移動到2,再把最後一層移動到3,最後再把其餘的從2移動到3,這是乙個直觀的關係,但是想列舉出來是很難的,也許當層數n 3時還可以模擬下,再大一些就不可能了,所以,...