有依賴的0 1揹包

2022-06-01 20:54:11 字數 2200 閱讀 3649

考慮到每個主件最多只有兩個附件,因此我們可以通過轉化,把原問題轉化為01揹包問題來解決,在用01揹包之前我們需要對輸入資料進行處理,把每一種物品歸類,即:把每乙個主件和它的附件看作一類物品。處理好之後,我們就可以使用01揹包演算法了。在取某件物品時,我們只需要從以下四種方案中取最大的那種方案:只取主件、取主件+附件1、取主件+附件2、既主件+附件1+附件2。很容易得到如下狀態轉移方程:

f[i,j]=max

其中,f[i,j]表示用j元錢,買前i類物品,所得的最大值,v[i,0]表示第i類物品主件的**,v[i,1]表示第i類物品第1個附件的**,v[i,2]表示第i類物品第2個附件的**,w[i,0],w[i,1],w[i,2]分別表示主件、第1個附件和第2個附件的重要度。

【牛客網】例子:

王強今天很開心,公司發給n元的年終獎。王強決定把年終獎用於購物,他把想買的物品分為兩類:主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子:

主件附件

電腦印表機,掃瞄器

書櫃圖書

書桌檯燈,文具

工作椅無

如果要買歸類為附件的物品,必須先買該附件所屬的主件。每個主件可以有 0 個、 1 個或 2 個附件。附件不再有從屬於自己的附件。王強想買的東西很多,為了不超出預算,他把每件物品規定了乙個重要度,分為 5 等:用整數 1 ~ 5 表示,第 5 等最重要。他還從網際網路上查到了每件物品的**(都是 10 元的整數倍)。他希望在不超過 n 元(可以等於 n 元)的前提下,使每件物品的**與重要度的乘積的總和最大。

設第 j 件物品的**為 v[j] ,重要度為 w[j] ,共選中了 k 件物品,編號依次為 j 1 , j 2 ,……, j k ,則所求的總和為:

v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 為乘號)

請你幫助王強設計乙個滿足要求的購物單。

輸入描述:

輸入的第 1 行,為兩個正整數,用乙個空格隔開:n m

(其中 n ( <32000 )表示總錢數, m ( <60 )為希望購買物品的個數。)

從第 2 行到第 m+1 行,第 j 行給出了編號為 j-1 的物品的基本資料,每行有 3 個非負整數 v p q

(其中 v 表示該物品的**( v<10000 ), p 表示該物品的重要度( 1 ~ 5 ), q 表示該物品是主件還是附件。如果 q=0 ,表示該物品為主件,如果 q>0 ,表示該物品為附件, q 是所屬主件的編號)

1 #include2

3using

namespace

std;45

6int max(int a,intb)7

10int

main()11;

14int valuemutipweight[61][3] = ;

15int dp[61][3201] = ;

16while(cin>>money>>num)

1731

else

if(value[lab][1]==0)//

第乙個附件

3236

else

//第二個附件

3741}42

4344

for(int i = 1;i<=num;i++)

4555

if(value[i][0]+value[i][1]<=j)//

帶第乙個附件

5661

if(value[i][0]+value[i][2]<=j)//

帶第二個附件

6267

if(value[i][0]+value[i][1]+value[i][2]<=j)//

帶兩個附件

6873}74

}75 cout<

7778

return0;

79 }

view code

其中value[61][3] 記錄60個物品的**,if(laber == 0)是主件,將其**寫到value[i][0]的位置,value*weight 的值寫到weight[i][0];if(laber == 1) 是第乙個附件,將其**寫到第一列的位置上,value*weight 的值寫到weight[i][1];laber==2同理。dp[num][money]表示用money這麼多錢購買了第num-1件物品所獲得的value*weight的最大值。

感謝:

有依賴的01揹包問題

王強今天很開心,公司發給n元的年終獎。王強決定把年終獎用於購物,他把想買的物品分為兩類 主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子 主件附件 電腦印表機,掃瞄器 書櫃圖書 書桌檯燈,文具 工作椅無 如果要買歸類為附件的物品,必須先買該附件所屬的主件。每個主件可以有 0 個 1 ...

有依賴的揹包

關鍵 當遞迴處理u結點的子樹返回時,進行分組揹包的決策,各個子樹中的結點可能非常多,可能有100多個結點,因此,如果以方案來劃分最多有2 100種類別,所以要改用體積來劃分 從j表示當前除去v u 的體積,j從 m v u 0 的體積中列舉 類別 k選取體積是0,是1.是j 選乙個 轉化為分組揹包問...

初識0 1依賴揹包

hdu3449 題意 給定物品的組數n和一開始擁有的錢數m,後面n行輸入代表n組物品,若要購買該組物品中的乙個或多個都需要先購買盒子,盒子無價值,每組物品中最開始兩個數bp和mi分別表示盒子的 和該組物品的種數,問用m元最多可獲得貨物的最 值是多少。思路 典型的有依賴的0 1揹包問題,根據dd大牛的...