fly1988happy
本文關(guān)鍵詞:0-1背包問題,由筆耕文化傳播整理發(fā)布。
0-1背包問題:
有N件物品和一個(gè)容量為V的背包。第i件物品的費(fèi)用是c[i],,價(jià)值是w[i]。求解將哪些物品裝入背包可使這些物品的費(fèi)用總和不超過背包容量,且價(jià)值總和最大。
這個(gè)問題的特點(diǎn)是:每種物品只有一件,可以選擇放或者不放。
算法基本思想:
利用動(dòng)態(tài)規(guī)劃思想 ,子問題為:f[i][v]表示前i件物品恰放入一個(gè)容量為v的背包可以獲得的最大價(jià)值。
其狀態(tài)轉(zhuǎn)移方程是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]} //這個(gè)方程非常重要,基本上所有跟背包相關(guān)的問題的方程都是由它衍生出來的。
解釋一下上面的方程:“將前i件物品放入容量為v的背包中”這個(gè)子問題,如果只考慮第i件物品放或者不放,那么就可以轉(zhuǎn)化為只涉及前i-1件物品的問題,即1、如果不放第i件物品,則問題轉(zhuǎn)化為“前i-1件物品放入容量為v的背包中”;2、如果放第i件物品,則問題轉(zhuǎn)化為“前i-1件物品放入剩下的容量為v-c[i]的背包中”(此時(shí)能獲得的最大價(jià)值就是f [i-1][v-c[i]]再加上通過放入第i件物品獲得的價(jià)值w[i])。則f[i][v]的值就是1、2中最大的那個(gè)值。
(注意:f[i][v]有意義當(dāng)且僅當(dāng)存在一個(gè)前i件物品的子集,其費(fèi)用總和為v。所以按照這個(gè)方程遞推完畢后,最終的答案并不一定是f[N] [V],而是f[N][0..V]的最大值。)
優(yōu)化空間復(fù)雜度:
以上方法的時(shí)間和空間復(fù)雜度均為O(N*V),其中時(shí)間復(fù)雜度基本已經(jīng)不能再優(yōu)化了,但空間復(fù)雜度卻可以優(yōu)化到O(V)。
上面f[i][v]使用二維數(shù)組存儲(chǔ)的,可以優(yōu)化為一維數(shù)組f[v],將主循環(huán)改為:
for i=1..N
for v=V..0
f[v]=max{f[v],f[v-c[i]]+w[i]};
即將第二層循環(huán)改為從V..0,逆序。
解釋一下:
假設(shè)最大容量M=10,物品個(gè)數(shù)N=3,物品大小w{3,4,5},物品價(jià)值p{4,5,6}。
當(dāng)進(jìn)行第i次循環(huán)時(shí),f[v]中保存的是上次循環(huán)產(chǎn)生的結(jié)果,即第i-1次循環(huán)的結(jié)果(i>=1)。所以f[v]=max{f[v],f[v-c[i]]+w[i]}這個(gè)式子中,等號(hào)右邊的f[v]和f[v-c[i]]+w[i]都是前一次循環(huán)產(chǎn)生的值。
當(dāng)i=1時(shí),f[0..10]初始值都為0。所以
f[10]=max{f[10],f[10-c[1]]+w[1]}=max{0,f[7]+4}=max{0,0+4}=4;
f[9]=max{f[9],f[9-c[1]]+w[1]}=max{0,f[6]+4}=max{0,0+4}=4;
......
f[3]=max{f[3],f[3-c[1]]+w[1]}=max{0,f[3]+4}=max{0,0+4}=4;
f[2]=max{f[2],f[2-c[1]]+w[1]}=max{0,f[2-3]+4}=0;//數(shù)組越界?
f[1]=0;
f[0]=0;
當(dāng)i=2時(shí),此時(shí)f[0..10]經(jīng)過上次循環(huán)后,都已經(jīng)被重新賦值,即f[0..2]=0,f[3..10]=4。利用f[v]=max{f[v],f[v-c[i]]+w[i]}這個(gè)公式計(jì)算i=2時(shí)的f[0..10]的值。
當(dāng)i=3時(shí)同理。
具體的值如下表所示:
因此,利用逆序循環(huán)就可以保證在計(jì)算f[v]時(shí),公式f[v]=max{f[v],f[v-c[i]]+w[i]}中等號(hào)右邊的f[v]和f[v-c[i]]+w[i]保存的是f[i-1][v]和f[i -1][v-c[i]]的值。
當(dāng)i=N時(shí),得到的f[V]即為要求的最優(yōu)值。
初始化的細(xì)節(jié)問題:
在求最優(yōu)解的背包問題中,一般有兩種不同的問法:1、要求“恰好裝滿背包”時(shí)的最優(yōu)解;2、求小于等于背包容量的最優(yōu)解,即不一定恰好裝滿背包。
這兩種問法,在初始化的時(shí)候是不同的。
1、要求“恰好裝滿背包”時(shí)的最優(yōu)解:
在初始化時(shí)除了f[0]為0其它f[1..V]均設(shè)為-∞,這樣就可以保證最終得到的f[N]是一種恰好裝滿背包的最優(yōu)解。如果不能恰好滿足背包容量,即不能得到f[V]的最優(yōu)值,則此時(shí)f[V]=-∞,這樣就能表示沒有找到恰好滿足背包容量的最優(yōu)值。
2、求小于等于背包容量的最優(yōu)解,即不一定恰好裝滿背包:
如果并沒有要求必須把背包裝滿,而是只希望價(jià)值盡量大,初始化時(shí)應(yīng)該將f[0..V]全部設(shè)為0。
總結(jié)
01背包問題是最基本的背包問題,它包含了背包問題中設(shè)計(jì)狀態(tài)、方程的最基本思想,另外,別的類型的背包問題往往也可以轉(zhuǎn)換成01背包問題求解。故一定要仔細(xì)體會(huì)上面基本思路的得出方法,狀態(tài)轉(zhuǎn)移方程的意義,以及最后怎樣優(yōu)化的空間復(fù)雜度。
0-1背包問題代碼:
代碼1
#include
本文關(guān)鍵詞:0-1背包問題,由筆耕文化傳播整理發(fā)布。
本文編號(hào):75320
本文鏈接:http://sikaile.net/wenshubaike/jyzy/75320.html