有依賴的揹包問題(樹形dp 揹包問題)

2021-09-10 19:57:11 字數 1543 閱讀 4185

acwing:

10.有 n 個物品和乙個容量是 v 的揹包。

物品之間具有依賴關係,且依賴關係組成一棵樹的形狀。如果選擇乙個物品,則必須選擇它的父點。

如下圖所示:

如果選擇物品5,則必須選擇物品1和2。這是因為2是5的父節點,1是2的父節點。

每件物品的編號是 i,體積是 vi,價值是 wi,依賴的父節點編號是 pi 。物品的下標範圍是 1…n。

求解將哪些物品裝入揹包,可使物品總體積不超過揹包容量,且總價值最大。輸出最大價值。

輸入格式

第一行有兩個整數 n,v,用空格隔開,分別表示物品個數和揹包容量。接下來有 n行資料,每行數表示乙個物品。第 i 行有三個整數 vi,wi,pi,用空格隔開,分別表示物品的體積、價值和依賴的物品號。如果 pi=−1,表示根節點。 資料保證所有物品構成一棵樹。

輸出格式

輸出乙個整數,表示最大價值。

資料範圍

1≤n,v≤100

1≤vi,wi≤100

父節點編號範圍:

內部結點:1≤pi≤n;

根節點 pi=−1;

輸入樣例

5 72 3 -1

2 2 1

3 5 1

4 7 2

3 6 2

輸出樣例:

11花了一天的時間來理解,懵懵懂懂,先寫下來留著以後弄清楚

/*揹包問題先迴圈物品再迴圈體積最後迴圈決策*/

#include

#include

#include

#include

#include

using namespace std;

const

int n =

110;

int n, m;

int h[n]

, e[n]

, ne[n]

, idx;

//tot,head以i為起點第一條邊儲存的位置

int v[n]

, w[n]

, f[n]

[n];

void

add(

int a,

int b)

void

dfs(

int u)

for(

int i = m; i >= v[u]

; i--

)//上面的迴圈把位置空出來了,這裡加進去,因為必須要選

f[u]

[i]= f[u]

[i - v[u]

]+ w[u]

;for

(int i =

0; i < v[u]

; i++

) f[u]

[i]=

0//小於的話,因為是有依賴條件的,所以

//如果選不成,那麼都選不了,就歸零

}int

main()

dfs(root)

; cout << f[root]

[m]<< endl;

return0;

}

DP 揹包系列問題 有依賴的揹包問題

有依賴的揹包問題又是乙個經典的揹包延伸問題,理解她可以讓我們更深刻地理解揹包中三重迴圈的順序邏輯,同時她也是樹形動規的雛形。題目一般情形 有 n nn 個物品和乙個容量是 v vv 的揹包。物品之間具有依賴關係,且依賴關係組成一棵樹的形狀。如果選擇乙個物品,則必須選擇它的父節點。每件物品的編號是 i...

樹形依賴揹包

問題大意 給出一棵樹,根節點為1,每個點有毒素和收穫。要求毒素不超過給定值的情況下使收穫最大。乙個點的父親節點被選取後這個點才能被選取。首先弄出dfs序,也記錄下每個點其子樹及自身的大小。每個點都能夠被選或不選,如果選了才會考慮它子樹。設f i j 表示dfs序上第i位上的點在其子樹及自身上選取了毒...

樹形揹包DP

include using namespace std const int n 310,m n 2 int h n ne m v m idx int w n int dp n n int n,m void add int a,int b void dfs int u for int j m j 0 ...