dp感覺還是有點陌生,但是這個必須要強化,這類題型實在是太常見了
一道比較經典的樹形dp入門題。。。。
設dp陣列
dp[root][0]表示對於該節點不選
dp[root][1]表示對於該節點擊
則有:
dp[root][0
]+=max
(dp[son][0
],dp[son][1
]);dp[root][1
]+=dp[son][0
];
主要可分為三個部分
一、建樹,直接用stl中vector即可
二、樹的遍歷,dfs
三、dp
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define ll long long
using
namespace std;
int n;
int dp[
6010][
5];//dp[root][1]表示參加宴會,dp[root][0]表示不參加宴會
int value[
6010];
int father[
6010];
vector<
int> tree[
6010];
void
dfs(
int root)
}int
main()
int a,b;
while(~
scanf
("%d%d"
,&a,
&b))
int root=1;
//找到根節點
for(
int i=
1;i<=n;i++)}
//cout(root)
; cout<<
max(dp[root][1
],dp[root][0
])<}return0;
}
其實感覺這題雖是乙個樹形結構,但是實際上也是可以用區間dp來求解的
開始實在沒想到,就連那麼簡單的前序遍歷數的遞迴都卡了一會
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define ll long long
using
namespace std;
int n;
int flag;
//防止最後乙個數後面出現空格
ll dp[35]
[35];
//dp陣列
int root[35]
[35];
//存放根節點
ll search
(int l,
int r)}}
return dp[l]
[r];
}void
preoder
(int l,
int r)
else
cout<[r];
preoder
(l,root[l]
[r]-1)
;preoder
(root[l]
[r]+
1,r);}
intmain()
}for
(int i=
1;i<=n;i++
) ll ans=
search(1
,n);
printf
("%lld\n"
,ans)
;preoder(1
,n);
cout
}
基本樹形dp及例題
include include include include include include define n 6005 樹形dp poj2342 using namespace std struct tree p n void dfs int x return int main while sc...
樹形DP 經典例題 沒有上司的舞會
一般樹形dp題目中都是其中某種狀況如果想要發生必須先完成先決條件 如 這道舞會題,要保證職員去參加舞會的話,必須滿足他的直接上司不去 還有的占領城堡的題,要占領乙個城堡必須先占領另乙個城堡。看到這樣的情況就考慮一下樹形dp 題目描述 ural大學有n個職員,編號為1 n。他們有從屬關係,也就是說他們...
樹形DP 樹形DP四例
是時候練一下dp了!我的題單 portkey f u,if fu,i 表示以u uu為根節點的子樹中保留i ii條樹枝的最大蘋果數 f u,i max f max f fu,i max這些題是菜,但也不能輕視啊!include using namespace std define in read i...