有依賴的揹包問題

問題 

這種揹包問題的物品間存在某種「依賴」的關係。也就是說,i依賴於j,表示若選物品i,則必須選物品j。爲了簡化起見,我們先設沒有某個物品既依賴於別的物品,又被別的物品所依賴;另外,沒有某件物品同時依賴多件物品。 
 

一、算法 

這裏將不依賴於別的物品的物品稱爲「主件」,依賴於某主件的物品稱爲「附件」。由這個問題的簡化條件可知所有的物品由若干主件和依賴於每個主件的一個附件集合組成。 

按照揹包問題的一般思路,僅考慮一個主件和它的附件集合。可是,可用的策略非常多,包括:一個也不選,僅選擇主件,選擇主件後再選擇一個附件,選擇主件後再選擇兩個附件……無法用狀態轉移方程來表示如此多的策略。(事實上,設有n個附件,則策略有2^n+1個,爲指數級。) 

考慮到所有這些策略都是互斥的(也就是說,你只能選擇一種策略),所以一個主件和它的附件集合實際上對應於 分組的揹包問題 中的一個物品組,每個選擇了主件又選擇了若干個附件的策略對應於這個物品組中的一個物品,其費用和價值都是這個策略中的物品的值的和。但僅僅是這一步轉化並不能給出一個好的算法,因爲物品組中的物品還是像原問題的策略一樣多。 

再考慮對每組中的物品應用一個簡單有效的優化:對於一個物品組中的物品,所有費用相同的物品只留一個價值最大的,不影響結果。

所以,我們可以對主件i的「附件集合」先進行一次01揹包,得到費用依次爲0..V-c[i]所有這些值時相應的最大價值f'[0..V-c[i]]。

那麼這個主件及它的附件集合相當於V-c[i]+1個物品的物品組,其中費用爲c[i]+k的物品的價值爲f'[k]+w[i]。也就是說原來指數級的策略中有很多策略都是冗餘的,通過一次01揹包後,將主件i轉化爲 V-c[i]+1個物品的物品組,就可以直接應用 分組的揹包問題 的算法解決問題了。 

更一般的問題 
更一般的問題是:依賴關係以圖論中「森林」的形式給出(森林即多叉樹的集合),也就是說,主件的附件仍然可以具有自己的附件集合,限制只是每個物品最多隻依賴於一個物品(只有一個主件)且不出現循環依賴。 

解決這個問題仍然可以用將每個主件及其附件集合轉化爲物品組的方式。唯一不同的是,由於附件可能還有附件,就不能將每個附件都看作一個一般的01 揹包中的物品了。若這個附件也有附件集合,則它必定要被先轉化爲物品組,然後用分組的揹包問題解出主件及其附件集合所對應的附件組中各個費用的附件所對應的價值。 

事實上,這是一種樹形DP,其特點是每個父節點都需要對它的各個兒子的屬性進行一次DP以求得自己的相關屬性。這已經觸及到了「泛化物品」的思想。這個「依賴關係樹」每一個子樹其實都等價於一件泛化物品,求某節點爲根的子樹對應的泛化物品相當於求其所有兒子的對應的泛化物品之和。 
 

 

二、案例

 

代碼: