樹形依賴揹包

2021-08-04 21:50:03 字數 1257 閱讀 1537

問題大意:給出一棵樹,根節點為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個的狀態。在轉移時...