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 ...