給定乙個物品集合s=,物品i具有重量wi和價值vi。揹包能承受能承受的最大載重量不超過w。揹包問題就是找到乙個物品子集s『屬於s,使得maxewi<=w。所謂01揹包就是物品要麼整個地選取,要麼不取。
首先我們先要肯定一件事,假設子問題(i,w)的最優裝載中含有物品i,則其中的子問題(i-1,w-wi)的裝載方案也一定是最優的。
證明:(反證法)假設子問題(i-1,w-wi)的裝載方案p不是最優的,則有乙個更優的裝載方案p』,將p』替換p然後在加上物品i將會比原來的最優裝載價值最大,與假設矛盾。
現設定乙個陣列v[i,w](i代表第幾個物品,w代表i物體的重量)表示將物品1到物品i的物品裝入載重量為w的揹包中所能獲得的最大價值,即子問題(i,w)的最大價值
(1)對於物品i能夠裝進揹包,則子問題(i,w)的最優解取決於物品i是否放進去
①如果物品i不放進去,則有v[i,w]=v[i-1,w]。就是說i不放進去,那麼容量為i的揹包的價值==容量為i-1的揹包的價值
②若將物品i放進去,則有v[i,w]=v[i-1,w-wi]+vi。若i放進去,那麼容量為i的揹包的價值==容量為i-1的揹包的價值加上第i個物品的價值
解析:相信大多數人都想不明白這句話的意思,若物品i能夠放進去,那麼一定是放進去後這個揹包的價值肯定大於沒放進去的價值大,這是錯誤的,假設有三個物品(1,1)
(2,3)(2,2)【(物品重量,價值)】,現我們規定揹包總重量限制於3,相信大家一眼就可以看出來,物品13的結合的價值沒有物品12結合的價值大,自然3不放的總價值大於放的總價值,12放進去後此時揹包容量已滿,但倘若物品3放進去,那麼揹包為了能夠容納3,它必將2剔除,所以說3不放的價值大於放的價值。
v[i-1,w-wi],i-1自然是說i的前乙個物品的序列號,而w-w[i]是剛好滿足放置i物品容量的前乙個,這裡的前不乙個不是固定於下圖示的斜對前,而是前乙個物品的容量+當前i物品的容量剛好等於此時列舉到的w
現在為大家推一便演算法,就明白了。
前提大家要先明確一件事,01揹包演算法精髓就是掃,假設揹包容量為w,物品個數為n,那麼可以假定的認為乙個二維陣列,行為第幾個物品,第一行為第乙個物品,第二行為第二個
物品,第n行為第n個物品。列為容量的多少,第一列是容量為1的揹包,第二列是容量為2的揹包,第三列為3,第n列為n。
給一組資料,物品號
wivi12
122110
33204
215揹包演算法如下的**所示01
2345
10012
1212122
0101222
222230
1012
2230324
0101525
3037
解析:1.第1個[2,12]物品,揹包容量為1時,2>1它進不了揹包,揹包容量為2時,剛好夠物品容量則進入揹包,所以揹包容量最大價值為12;揹包容量為3,4,5時1號物品都可以進入揹包,所以價值均為12。
2.第2個[1,10]物品,揹包容量為1時,它的前乙個物品c[1][1-1]=0+10(放進第二個物品的價值)=10大於不放,所以放;揹包容量為2時,對於前乙個揹包c[2-1][2-1]=0+12大於它的前乙個容量的價值c[1][2],所以此時對於前一階段要放置2號物品
揹包容量為3,對於前一物品c[2-1][3-1]=12,若放2號物品,則12+10>不放,所以放,而對於揹包容量都為4,5時,都是放置2號物品的價值大於不放,所以都放
3.第3個[3,20]物品,揹包容量為1,2時,w[3]均大於揹包容量,所以不放,承接前一物品揹包容量1,2的價值;當揹包容量為3的時候,此時c[3-1][0]+20(放),小於放置物品1,2的價值,所以3不放,放1,2;而對於揹包容量為4的時候,c[2][1]=10(這個說明減去放置物品3的容量,此時揹包中還剩下物品1)+20=30,此時的價值大於放1,2,,則放置1,3。。。。。
4.同理
view code
int c[10][100];/*一維陣列的對應每種情況的最大價值
*/int knapsack(int m,int n)//
m是價值的限制,n是物品的個數
else c[i][j]=c[i-1
][j];
}return
(c[n][m]);
}
view code
for(i=1;i1;i++)} for(i=sum;i>=0;i--)//
輸出 }
揹包精講之 01揹包
了解01揹包時應該注意01揹包在問法上的差別 初始化分兩種情況 1 如果揹包要求正好裝滿則初始化 f 0 0,f 1 w inf 2 如果不需要正好裝滿 f 0 v 0 題目 有n 件物品和乙個容量為 v的揹包。第 i件物品的費用是 c i 價值是 w i 求解將哪些物品裝入揹包可使價值總和最大。整...
揹包問題精講2018 08 09
第一道題 這道題就是一道非常的01揹包模板,不過需要注意到題目的條件還需要乘上重要性,也就是價值 原價值 重要度,其他的就按照01揹包模板照打即可。附上 吧 include using namespace std const int maxn 100000 20 int a maxn w maxn ...
揹包九講之 01揹包
01揹包是最基礎的揹包問題,其中01代表的就是第i個物品的選或不選,在此先設v i 為體積,w i 為價值。很顯然,我們可以使用二位陣列dp i j 來表示前i個物品在揹包容量為j的時候可存放的最大價值。首先dp 0 0 0是很顯然的。而計算dp i j 時,存在01兩種情況 選或不選第i件物品。1...