[轉(zhuǎn)]背包問題九講v1.0(P01:01背包問題)

題目

有N件物品和一個(gè)容量為V的背包。第i件物品的費(fèi)用是c[i]春缕,價(jià)值是w[i]。求解將哪些物品裝入背包可使價(jià)值總和最大艘蹋。

基本思路

這是最基礎(chǔ)的背包問題锄贼,特點(diǎn)是:每種物品僅有一件,可以選擇放或不放女阀。
用子問題定義狀態(tài):即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)的問題的方程都是由它衍生出來的。所以有必要將它詳細(xì)解釋一下:“將前i件物品放入容量為v的背包中”這個(gè)子問題冯键,若只考慮第i件物品的策略(放或不放)惹盼,那么就可以轉(zhuǎn)化為一個(gè)只牽扯前i-1件物品的問題。如果不放第i件物品琼了,那么問題就轉(zhuǎn)化為“前i-1件物品放入容量為v的背包中”逻锐,價(jià)值為f[i-1][v];如果放第i件物品雕薪,那么問題就轉(zhuǎn)化為“前i-1件物品放入剩下的容量為v-c[i]的背包中”昧诱,此時(shí)能獲得的最大價(jià)值就是f[i-1][v-c[i]]再加上通過放入第i件物品獲得的價(jià)值w[i]

優(yōu)化空間復(fù)雜度

以上方法的時(shí)間和空間復(fù)雜度均為O(N*V)所袁,其中時(shí)間復(fù)雜度基本已經(jīng)不能再優(yōu)化了盏档,但空間復(fù)雜度卻可以優(yōu)化到O(V)
先考慮上面講的基本思路如何實(shí)現(xiàn)燥爷,肯定是有一個(gè)主循環(huán)i=1..N蜈亩,每次算出來二維數(shù)組f[i][0..V]的所有值。那么前翎,如果只用一個(gè)數(shù)組f[0..V]稚配,能不能保證第i次循環(huán)結(jié)束后f[v]中表示的就是我們定義的狀態(tài)f[i][v]呢?f[i][v]是由f[i-1][v]f[i-1][v-c[i]]兩個(gè)子問題遞推而來港华,能否保證在推f[i][v]時(shí)(也即在第i次主循環(huán)中推f[v]時(shí))能夠得到f[i-1][v]f[i-1][v-c[i]]的值呢道川?事實(shí)上,這要求在每次主循環(huán)中我們以v=V..0的順序推f[v]立宜,這樣才能保證推f[v]時(shí)f[v-c[i]]保存的是狀態(tài)f[i-1][v-c[i]]的值冒萄。偽代碼如下:

for i=1..N
    for v=V..0
        f[v]=max{f[v],f[v-c[i]]+w[i]};

其中的f[v]=max{f[v],f[v-c[i]]}一句恰就相當(dāng)于我們的轉(zhuǎn)移方程f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]},因?yàn)楝F(xiàn)在的f[v-c[i]]就相當(dāng)于原來的f[i-1][v-c[i]]橙数。如果將v的循環(huán)順序從上面的逆序改成順序的話尊流,那么則成了f[i][v]f[i][v-c[i]]推知,與本題意不符灯帮,但它卻是另一個(gè)重要的背包問題P02最簡捷的解決方案崖技,故學(xué)習(xí)只用一維數(shù)組解01背包問題是十分必要的。
事實(shí)上钟哥,使用一維數(shù)組解01背包的程序在后面會(huì)被多次用到迎献,所以這里抽象出一個(gè)處理一件01背包中的物品過程,以后的代碼中直接調(diào)用不加說明瞪醋。
過程ZeroOnePack,表示處理一件01背包中的物品装诡,兩個(gè)參數(shù)cost银受、weight分別表明這件物品的費(fèi)用和價(jià)值践盼。

procedure ZeroOnePack(cost,weight)
    for v=V..cost
        f[v]=max{f[v],f[v-cost]+weight}

注意這個(gè)過程里的處理與前面給出的偽代碼有所不同。前面的示例程序?qū)懗?code>v=V..0是為了在程序中體現(xiàn)每個(gè)狀態(tài)都按照方程求解了宾巍,避免不必要的思維復(fù)雜度咕幻。而這里既然已經(jīng)抽象成看作黑箱的過程了,就可以加入優(yōu)化顶霞。費(fèi)用為cost的物品不會(huì)影響狀態(tài)f[0..cost-1]肄程,這是顯然的。
有了這個(gè)過程以后选浑,01背包問題的偽代碼就可以這樣寫:

for i=1..N
    ZeroOnePack(c[i],w[i]);

初始化的細(xì)節(jié)問題

我們看到的求最優(yōu)解的背包問題題目中蓝厌,事實(shí)上有兩種不太相同的問法。有的題目要求“恰好裝滿背包”時(shí)的最優(yōu)解古徒,有的題目則并沒有要求必須把背包裝滿拓提。一種區(qū)別這兩種問法的實(shí)現(xiàn)方法是在初始化的時(shí)候有所不同。
<p>如果是第一種問法隧膘,要求恰好裝滿背包代态,那么在初始化時(shí)除了f[0]0其它f[1..V]均設(shè)為-∞,這樣就可以保證最終得到的f[N]是一種恰好裝滿背包的最優(yōu)解疹吃。
如果并沒有要求必須把背包裝滿蹦疑,而是只希望價(jià)格盡量大,初始化時(shí)應(yīng)該將f[0..V]全部設(shè)為0萨驶。
<p>為什么呢歉摧?可以這樣理解:初始化的f數(shù)組事實(shí)上就是在沒有任何物品可以放入背包時(shí)的合法狀態(tài)。如果要求背包恰好裝滿篡撵,那么此時(shí)只有容量為0的背包可能被價(jià)值為0的nothing“恰好裝滿”判莉,其它容量的背包均沒有合法的解,屬于未定義的狀態(tài)育谬,它們的值就都應(yīng)該是-∞了券盅。如果背包并非必須被裝滿,那么任何容量的背包都有一個(gè)合法解“什么都不裝”膛檀,這個(gè)解的價(jià)值為0锰镀,所以初始時(shí)狀態(tài)的值也就全部為0了。
這個(gè)小技巧完全可以推廣到其它類型的背包問題咖刃,后面也就不再對(duì)進(jìn)行狀態(tài)轉(zhuǎn)移之前的初始化進(jìn)行講解泳炉。

小結(jié)

01背包問題是最基本的背包問題,它包含了背包問題中設(shè)計(jì)狀態(tài)嚎杨、方程的最基本思想花鹅,另外,別的類型的背包問題往往也可以轉(zhuǎn)換成01背包問題求解枫浙。故一定要仔細(xì)體會(huì)上面基本思路的得出方法刨肃,狀態(tài)轉(zhuǎn)移方程的意義古拴,以及最后怎樣優(yōu)化的空間復(fù)雜度。

轉(zhuǎn)載:dd_engi 的背包九講

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末真友,一起剝皮案震驚了整個(gè)濱河市黄痪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盔然,老刑警劉巖桅打,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異愈案,居然都是意外死亡挺尾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門刻帚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來潦嘶,“玉大人,你說我怎么就攤上這事崇众〉嘟” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵顷歌,是天一觀的道長锰蓬。 經(jīng)常有香客問我,道長眯漩,這世上最難降的妖魔是什么芹扭? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮赦抖,結(jié)果婚禮上舱卡,老公的妹妹穿的比我還像新娘。我一直安慰自己队萤,他們只是感情好轮锥,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著要尔,像睡著了一般舍杜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赵辕,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天既绩,我揣著相機(jī)與錄音,去河邊找鬼还惠。 笑死饲握,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播救欧,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼歪今,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了颜矿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤嫉晶,失蹤者是張志新(化名)和其女友劉穎骑疆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體替废,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡箍铭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了椎镣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诈火。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖状答,靈堂內(nèi)的尸體忽然破棺而出冷守,到底是詐尸還是另有隱情,我是刑警寧澤惊科,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布拍摇,位于F島的核電站,受9級(jí)特大地震影響馆截,放射性物質(zhì)發(fā)生泄漏充活。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一蜡娶、第九天 我趴在偏房一處隱蔽的房頂上張望混卵。 院中可真熱鬧,春花似錦窖张、人聲如沸幕随。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽合陵。三九已至,卻和暖如春澄阳,著一層夾襖步出監(jiān)牢的瞬間拥知,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工碎赢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留低剔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像襟齿,于是被迫代替她去往敵國和親姻锁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容