揹包問題中求次優解,第K優解的方法

2021-06-17 01:32:49 字數 902 閱讀 4602

對於求次優解、第k優解類的問題,如果相應的最優解問題能寫出狀態轉移方程、用動態規劃解決,那麼求次優解往往可以相同的複雜度解決,第k優解則比求最優解的複雜度上多乙個係數k。

其基本思想是將每個狀態都表示成有序佇列,將狀態轉移方程中的max/min轉化成有序佇列的合併。這裡仍然以01揹包為例講解一下。

首先看01揹包求最優解的狀態轉移方程:f[i][v]=max。如果要求第k優解,那麼狀態f[i][v]就應該是乙個大小為k的陣列f[i][v][1..k]。其中f[i][v][k]表示前i個物品、揹包大小為v時,第k優解的值。「f[i][v]是乙個大小為k的陣列」這一句,熟悉c語言的同學可能比較好理解,或者也可以簡單地理解為在原來的方程中加了一維。顯然f[i][v][1..k]這k個數是由大到小排列的,所以我們把它認為是乙個有序佇列。

然後原方程就可以解釋為:f[i][v]這個有序佇列是由f[i-1][v]和f[i-1][v-c[i]]+w[i]這兩個有序佇列合併得到的。有序佇列f[i-1][v]即f[i-1][v][1..k],f[i-1][v-c[i]]+w[i]則理解為在f[i-1][v-c[i]][1..k]的每個數上加上w[i]後得到的有序佇列。合併這兩個有序佇列並將結果(的前k項)儲存到f[i][v][1..k]中的複雜度是o(k)。最後的答案是f[n][v][k]。總的複雜度是o(nvk)。

為什麼這個方法正確呢?實際上,乙個正確的狀態轉移方程的求解過程遍歷了所有可用的策略,也就覆蓋了問題的所有方案。只不過由於是求最優解,所以其它在任何乙個策略上達不到最優的方案都被忽略了。如果把每個狀態表示成乙個大小為k的陣列,並在這個陣列中有序的儲存該狀態可取到的前k個最優值。那麼,對於任兩個狀態的max運算等價於兩個由大到小的有序佇列的合併。

另外還要注意題目對於「第k優解」的定義,將策略不同但權值相同的兩個方案是看作同乙個解還是不同的解。如果是前者,則維護有序佇列時要保證佇列裡的數沒有重複的。

JZOJ P1281 DP 揹包的第k優解

kaike 傳送門看了半天,不會寫 沒見過這種題型,看了揹包九講,然而只有很簡單的幾句話 我認為就是多加了一維,變成三維陣列 由於必須恰好等於包的容量,所以要賦最小值 然而不能那樣遞推為什麼我也不知道 還沒悟出來 嗯加油1 include2 using namespace std 3long f 5...

hdu2639 01揹包k優解)

沒怎麼理解題意,題意 有n件物品,揹包體積為v,給出一行價值和一行花費,求第k優解,每個物品只能取一次。思路 不考慮k優解,顯然是個簡單的01揹包,1維的陣列足夠表示。即便要求k優解,在k 30的條件下,此題再加1維也沒什麼好說的,用dp j k 表示揹包體積為j時的k優解,一開始不知道怎麼轉移,原...

dp之01揹包hdu2639(第k優解)

題意 給出一行價值,一行體積,讓你在v體積的範圍內找出第k大的值.注意,不要 和它的第一題混起來,它第一行是價值,再是體積 思路 首先dp i j 代表的是在體積為i的時候第j優解為dp i j 那麼,我們就可以這樣思考,i對應體積,那麼如果只是一維的dp i 代表的應該是體積為i時的最大值,那麼同...