01揹包問題內層循環必須是逆序的解釋

01揹包問題的具體描述自行百度:

有N件物品和一個容量爲V的揹包。第i件物品的重量是c[i],價值是w[i]。
求解將哪些物品裝入揹包可使這些物品的重量總和不超過揹包容量,且價值總和最大。

(01揹包中這些物品每種都只有1個,每個物品只能裝一次)

基本問題

用子問題定義狀態:即f[i][v]表示前i件物品恰放入一個容量爲v的揹包可以獲得的最大價值。
則其狀態轉移方程便是:f[i][v]=max{ f[i-1][v], f[i-1][v-c[i]]+w[i] }。可以壓縮空間,f[v]=max{f[v],f[v-c[i]]+w[i]}

這個方程非常重要,基本上所有跟揹包相關的問題的方程都是由它衍生出來的。所以有必要將它詳細解釋一下:
“將前i件物品放入容量爲v的揹包中”這個子問題,若只考慮第i件物品的策略(放或不放),那麼就可以轉化爲一個只牽扯前i-1件物品的問題。
如果不放第i件物品,那麼問題就轉化爲“前i-1件物品放入容量爲v的揹包中”,價值爲f[i-1][v];如果放第i件物品,
那麼問題就轉化爲“前i-1件物品放入剩下的容量爲v-c[i]的揹包中”,
此時能獲得的最大價值就是f [i-1][v-c[i]]再加上通過放入第i件物品獲得的價值w[i] 即f[i-1][v-c[i]]+w[i]。

爲什麼逆序

逆序的關鍵就在於這個狀態轉移方程

f[i][v]只與f[i-1][v]和f[i-1][v-C[i]]有關,即只和i-1時刻狀態有關,所以我們只需要用一維數組f[]來保存i-1時的狀態f[]。
假設i-1時刻的f[]爲{a0,a1,a2,…,av},那麼i時刻的f[]中第v個應該爲max(av,av-C[i]+W[i])即max(f[v],f[v-C[i]]+W[i]),

這就需要我們遍歷V時逆序遍歷,這樣才能保證求i時刻f[v]時f[v-C[i]]是i-1時刻的值。如果正序遍歷則當求f[v]時
其前面的f[0],f[1],…,f[v-1]都已經改變過,裏面存的都不是i-1時刻的值,這樣求f[v]時利用f[v-C[i]]必定是錯的值。最後f[V]即爲最大價值。

數組遍歷有時候必須逆序大多是這個原因。

發佈了25 篇原創文章 · 獲贊 34 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章