問題大意:給出一棵樹,根節點為1,每個點有毒素和收穫。要求毒素不超過給定值的情況下使收穫最大。乙個點的父親節點被選取後這個點才能被選取。
首先弄出dfs序,也記錄下每個點其子樹及自身的大小。每個點都能夠被選或不選,如果選了才會考慮它子樹。 設f
[i][
j]表示dfs序上第i位上的點在其子樹及自身上選取了毒素和為j的點所能獲得的最大收益。(下面x指dfs序上第i位代表的點)如果j
st[x
] ,f[
i][j
]=f[
i+si
ze[x
]][j
] 。代表這個點及其子樹都不能選(+s
ize[
x]代表在dfs序上跳過這個點的子樹) 如果j
≥cos
t[x]
,f[i
][j]
=max
(f[i
+1][
j−c[
x]]+
v[x]
,f[i
+siz
e[x]
][j]
) 。
注意是否會出現負收益,並選擇是否需要再與0比較。
#include
#include
#include
#include
using
namespace
std ;
bool read ( int &x, char c = getchar(), bool flag = false )
const
int maxn = 5010, maxm = maxn<<1, zhf = 1
<<28 ;
int ans, n, m, e, be[maxn], to[maxm], nxt[maxm], v[maxn], c[maxn], dfn[maxn], rdn[maxn], clk, size[maxn], f[maxn][maxn] ;
void add ( int x, int y )
void dfs ( int x, int fa )
}int main()
for ( i = 1 ; i < n ; i ++ )
dfs(1,1) ;
for ( i = n ; i ; i -- )
printf ( "%d\n", f[1][m] ) ;
return
0 ;}
感謝wearry在模擬賽中提到這個知識點。 有依賴的揹包問題(樹形dp 揹包問題)
acwing 10.有 n 個物品和乙個容量是 v 的揹包。物品之間具有依賴關係,且依賴關係組成一棵樹的形狀。如果選擇乙個物品,則必須選擇它的父點。如下圖所示 如果選擇物品5,則必須選擇物品1和2。這是因為2是5的父節點,1是2的父節點。每件物品的編號是 i,體積是 vi,價值是 wi,依賴的父節點...
HDU 攻城堡 (依賴揹包 樹形dp)
acboy很喜歡玩一種戰略遊戲,在乙個地圖上,有n座城堡,每座城堡都有一定的寶物,在每次遊戲中acboy允許攻克m個城堡並獲得裡面的寶物。但由於地理位置原因,有些城堡不能直接攻克,要攻克這些城堡必須先攻克其他某乙個特定的城堡。你能幫acboy算出要獲得盡量多的寶物應該攻克哪m個城堡嗎?每個測試例項首...
樹形揹包總結
目錄 2 有物品大小 3 物品大小為1,有k的限制。二 dfs序上dp 例題1例題2 例題3總結下 樹形揹包,就是說,在樹上選乙個包含根的連通塊,或揹包存在依賴關係 選父才能選子 或者需要知道每個點的子樹中選了多少 通常,我們有兩種方法 我們設 dp i,j 表示在i的子節點中選j個的狀態。在轉移時...