HDU 1561 樹形DP 揹包

2021-09-08 10:29:25 字數 1016 閱讀 9008

題目鏈結

題目大意:從樹根開始取點。最多取m個點,問最大價值。

解題思路

cost=1的樹形揹包。

有個虛根0,取這個虛根也要cost,所以最後的結果是dp[0][m+1]。

本題是cost=1的特殊揹包問題,在兩個for迴圈上有乙個優化。

for(f+1...j....cost)

for(1....k...j-cost)

其中f為當前已經dfs子結點個數。之所以+1,是因為根要預留乙個空間。

f+=dfs(t),dfs(t)返回的是子點t的f+1。

其實可以直接把f+1寫成m+1, 不過要多好多次沒必要的迴圈。

#include "

cstdio

"#include

"vector

"#include

"cstring

"using

namespace

std;

#define maxn 205

intn,m,u,dp[maxn][maxn],w[maxn],head[maxn],tol;

struct

edge

e[maxn];

void addedge(int u,int

v)int dfs(int

root)}}

return f+1;}

intmain()

dfs(0);

printf(

"%d\n

",dp[0][m+1

]); memset(dp,

0,sizeof

(dp));

}}

11910646

2014-10-19 14:01:53

accepted

1561

0ms400k

1099 b

c++physcal

HDU 1561 樹形dp 揹包

分析 攻下一座城堡的前提是要先攻下它的前驅城堡,建立乙個以0為根結點的樹,他的權值為0 dp i,j 表示以i為根結點去j個的最大值。dp i,1 v i v i 為攻下i城堡獲得的寶藏 對與u結點取j 1個,可以轉化為以孩子i為根取k個 以自己為根取j 1 k個和自己取j 1個的最大值 為什麼是j...

HDU 1561(樹形dp 揹包問題)

題目 click 每個城堡被攻克,必須之前有乙個特定的城堡被攻克,才能攻占這個城堡。形成了一種子節點與父節點的關係,聯想到樹形dp取解決。走子節點必先走其父親節點,一次建樹,若無則父親節點為0 dp i j 表示以i為節點,取j個城堡寶藏獲得的最大值。include include include ...

hdu 1561 樹形dp 01揹包

很容易想到如果是要攻克v城需要先攻克u城的話,可以建u到v的邊。但是如果能夠直接攻克u城呢?無邊可建,這樣就無法形成一棵樹。因此虛擬出乙個0結點去連線可直接攻克的城。這樣只需多打一次0城即可。定義狀態dp i j 表示當前結點為i時,選取j個節點 j為i的子節點或i 能獲得的最大價值。dp u j ...