rq06金明的預算方案題解

2021-06-16 22:02:42 字數 2307 閱讀 1499

古老的揹包題了,動態規劃的氣息濃郁。

在著名的揹包九講裡面有詳細的介紹,我先搬運工一下。

7有依賴的揹包問題

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

7.2演算法 這個問題由noip2006中「金明的預算方案」一題擴充套件而來。遵從該題的提法,將不依賴於別的物品的物品稱為「主件」,依賴於某主件的物品稱為「附件」。由這個問題的簡化條件可知所有的物品由若干主件和依賴於每個主件的乙個附件集合組成。 按照揹包問題的一般思路,僅考慮乙個主件和它的附件集合。可是,可用的策略非常多,包括:乙個也不選,僅選擇主件,選擇主件後再選擇乙個附件,選擇主件後再選擇兩個附件……無法用狀態轉移方程來表示如此多的策略。事實上,設有n個附件,則策略有2n+1個,為指數級。 考慮到所有這些策略都是互斥的(也就是說,你只能選擇一種策略),所以乙個主件和它的附件集合實際上對應於6中的乙個物品組,每個選擇了主件又選擇了若干個附件的策略對應於這個物品組中的乙個物品,其費用和價值都是這個策略中的物品的值的和。但僅僅是這一步轉化並不能給出乙個好的演算法,因為物品組中的物品還是像原問題的策略一樣多。 再考慮對每組內的物品應用2.3中的優化。我們可以想到,對於第k個物品組中的物品,所有費用相同的物品只留乙個價值最大的,不影響結果。所以,可以對主件k的「附件集合」先進行一次01揹包,得到費用依次為0...v−ck所有這些值時相應的最大價值fk[0...v−ck]。那麼,這個主件及它的附件集合相當於v−ck+1個物品的物品組,其中費用為v的物品的價值為fk[v−ck]+wk,v的取值範圍是ck≤v≤v。 也就是說,原來指數級的策略中,有很多策略都是冗餘的,通過一次01揹包後,將主件k及其附件轉化為v−ck+1個物品的物品組,就可以直接應用6的演算法解決問題了。 

7.3較一般的問題 更一般的問題是:依賴關係以圖論中「森林」3的形式給出。也就是說,主件的附件仍然可以具有自己的附件集合。限制只是每個物品最多隻依賴於乙個物品(只有乙個主件)且不出現迴圈依賴。解決這個問題仍然可以用將每個主件及其附件集合轉化為物品組的方式。唯一不同的是,由於附件可能還有附件,就不能將每個附件都看作乙個一般的01揹包中的物品了。若這個附件也有附件集合,則它必定要被先轉化為物品組,然後用分組的揹包問題解出主件及其附件集合所對應的附件組中各個費用的附件所對應的價值。 事實上,這是一種樹形動態規劃,其特點是,在用動態規劃求每個父節點的屬性之前,需要對它的各個兒子的屬性進行一次動態規劃式的求值。這已經觸及到了「泛化物品」的思想。看完8後,你會發現這個「依賴關係樹」每乙個子樹都等價於一件泛化物品,求某節點為根的子樹對應的泛化物品相當於求其所有兒子的對應的泛化物品之和。 7.4小結 noip2006的那道揹包問題我做得很失敗,寫了上百行的**,卻一分未得。後來我通過思考發現通過引入「物品組」和「依賴」的概念可以加深對這題的理解,還可以解決它的推廣問題。用物品組的思想考慮那題中極其特殊的依賴關係:物品不能既作主件又作附件,每個主件最多有兩個附件,可以發現乙個主件和它的兩個附件等價於乙個由四個物品組成的物品組,這便揭示了問題的某種本質。 後來,我在《揹包問題九講》第一版中總結此事時說:「失敗不是什麼丟人的事情,從失敗中全無收穫才是。」之後的noip2007的比賽中,我得了滿分。

上面是純搬運的,如果是初接觸動態規劃,是很有必要把揹包九講看一遍。

這道題目簡單的來說就是把附件考慮到主件裡面來,迴圈的時候只考慮主件,而主件存在不拿,拿主件,拿主件加附件1,拿主件加附件2,拿主件加附件1和2一共五種情況。如果之前能把輸入的資料處理好了,狀態轉移的部分幾乎和01揹包一樣。

#include#includestruct hey

a[67];

int max(int a,int b,int c)

main()

; scanf("%d %d",&n,&m);

n=n/10;

for(i=1;i<=m;i++)

scanf("%d %d %d",&v[i],&p[i],&q[i]);

for(i=1;i<=m;i++)

}m=j-1;

for(i=1;i<=m;i++)

if(q[i]!=0)

}for(i=1;i<=m;i++)

for(k=1;k<=a[i].flag;k++)

for(j=n;j>=0;j--)

if(j-a[i].v[k]>=0)

f[i][j]=max(f[i-1][j-a[i].v[k]]+a[i].w[k],f[i-1][j],f[i][j]);

else f[i][j]=max(0,f[i][j],f[i-1][j]);

printf("%d\n",f[m][n]*10);

}

金明的預算方案

problem description 金明今天很開心,家裡購置的新房就要領鑰匙了,新房裡有一間金明自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說 你的房間需要購買哪些物品,怎麼布置,你說了算,只有不超過n元錢就行 今天一早,金明就開始做預算了,他把想買的物品分為兩類 主件和附件,附件是從屬...

金明的預算方案

題目描述 金明今天很開心,媽媽昨天對他說 你的房間需要購買哪些物品,你說了算,只要不超過n元錢就行 今天一早,金明就開始做預算了,他把想買的物品分為兩類 主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子 主件 附件 電腦 印表機,掃瞄器 書櫃 圖書 書桌 檯燈,文具 工作椅 無 如果...

金明的預算方案

題目 分析一下,若想選附件,必然要選其主件,看上去是個依賴揹包問題,也就是樹形dp,但是這個題目限制了乙個問題,也就是乙個主件至多有2個附件,那麼也就只有4種方案,只選主件,選主件和附件1,選主件和附件2,選主件和附件1和附件2。只有4種方案,所以將其轉化成為乙個組合揹包問題。include inc...