01揹包的內循環逆序解析

揹包九講:01揹包的內循環逆序問題

對於01揹包,用二維數組做DP的情況如下:

F[i,v]代表,在揹包容量爲v的情況下,從前i件物品中選出若干件(因揹包容量的限制,可能不會所有i件都在裏面,取最大值時揹包裏應該是權值相對較大的那些物品)所能得到的最大價值。

第一句對dp設置初始條件。

兩個for循環遍歷所有的情況:i從1~N表示從i件物品中選取,v從ci~V表示揹包的大小(現在考慮的是第i件物品的放與不放,因此揹包應該至少大於等於i物品的費用,否則無意義)

最關鍵的問題在於max{F[i-1,v],F[i-1,v-Ci]+wi}這一句

F[i-1,v]表示在揹包容量v的情況下,從前i-1個物品中怎樣放置使價值最大,這也代表,對於第i件物品,我們不選擇將它放入揹包,而去從前i-1個物品中選擇放置策略,但這與F[i-1,v-Ci]是不同的,因爲我們現在只是選擇不把這個i放進去,而不代表我們要削減揹包的容量。

F[i-1,v-Ci]+wi表示,在揹包容量爲v的情況下,我們選擇將這個第i件物品放入揹包的情況。此時F[i,v]應該是,在放入之前揹包的最大價值,加上放入之後的最大價值。而放入之前揹包的最大價值爲F[i-1,v-Ci]。

仔細思考F[i-1,v]與F[i-1,v-Ci]的區別:

現在我們計算的是F[i,v],也就是說揹包的容量已經定死爲v了,F[i-1,v]是因爲我們放棄了將i加入揹包,揹包的容量是不變的。而F[i-1,v-Ci]是因爲,現在我們選擇將i加入揹包,也就是說,這個揹包至少已經有一個i了,這個i的容量也爲Ci了,而揹包總共爲v,現在要計算它的最大價值,就要加上在v-Ci中,在前i-1個物品中做選擇使揹包容量最大的值了。

這個方法使用的是二維數組,而實際上,i時刻的結果只與i-1時刻下的策略有關。

我們考慮用一個一維數組來進行dp。

對於一維數組來說,它無法保存兩個狀態i與v,但是,由於i只與i-1有關,因此如果我們逐步更新i,在i時刻進行放置之前,F[v]實際上保存的就是i-1下的最優值,而更新後直到i+1時刻的放置策略之前,F[v]都保存的是i下的最優值。

因此:

首先解釋下max{F[v],F[v-Ci]+Wi}:

我們已經明確了,F[v]表示的是i下的最優值。

而在i下,在進行到F[v]=max{F[v],F[v-Ci]+Wi};之前,我們看F[v],這個時候的F[v]實際上是保存的是i-1下揹包容量爲v的最優值,因此:

在對F[v]賦值之前,F[v]表示,不考慮第i件物品,只考慮前i-1個物品的情況下,在揹包容量爲v下的最優解。

而F[v-Ci]表示,在i-1下,揹包容量爲v-Ci的最優解,再加上右邊的Wi,就表示一定將i放入揹包的情況。

 

在解釋下關於逆序的問題:

從上面可以看到,對v來說,它是從V遞減到Ci的,而且一定只能是逆序,這是因爲:

從內循環來說,每一次內循環,都相當於更新在i下,揹包容量爲v最優解。更新之前,F[v]表示i-1下的最優解而一旦賦值結束,F[v]就表示i下的最優解了。

如果爲順序,當我們進行到F[v]時,要使用到F[v-Ci],但是這個F[v-Ci]必須是i-1下的最優解,而由於順序的原因在我們將v遞增到(順序的情況下)v時已經經歷了v-Ci這個揹包容量了,換句話說,此時v下的F[v-Ci]已經代表的是i下揹包容量爲v-Ci的最優解了而我們需要的是i-1下,揹包容量爲v-Ci的最優解!

因此,我們必須要使用逆序,這樣當進行到v時,F[v-Ci]還未更新,它還依然表示i-1下的最優解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章