向下搜一遍,向上搜一遍
http://acm.hdu.edu.cn/showproblem.php?pid=1561
對(duì)每一個(gè)節(jié)點(diǎn)進(jìn)行一次背包,好題啊,兩個(gè)DP樹(shù)形和背包結(jié)合的
http://acm.hdu.edu.cn/showproblem.php?pid=1011
這道是當(dāng)年省賽的壓軸題,但是感覺(jué)和上一道差不多,一樣的難度,唯一不同的就是這個(gè)是無(wú)向圖(我由于思維慣性拿來(lái)當(dāng)單向圖作,糾結(jié)了好久。。。)
樹(shù)形+背包+臨街表
下邊是從天涯空間里找出來(lái)的練習(xí)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3201
http://acm.pku.edu.cn/JudgeOnline/problem?id=3107
http://acm.pku.edu.cn/JudgeOnline/problem?id=1655
http://acm.pku.edu.cn/JudgeOnline/problem?id=2378
http://acm.pku.edu.cn/JudgeOnline/problem?id=3140
http://acm.hdu.edu.cn/showproblem.php?pid=2242
http://acm.timus.ru/problem.aspx?space=1&num=1018
http://acm.pku.edu.cn/JudgeOnline/problem?id=1947
http://acm.pku.edu.cn/JudgeOnline/problem?id=2057
http://acm.pku.edu.cn/JudgeOnline/problem?id=2486
http://acm.pku.edu.cn/JudgeOnline/problem?id=1848
http://acm.pku.edu.cn/JudgeOnline/problem?id=2152
http://acm.hdu.edu.cn/showproblem.php?pid=1520
(第一個(gè)樹(shù)形DP,附代碼)
最最簡(jiǎn)單的樹(shù)形DP
還學(xué)習(xí)了父子兄弟結(jié)構(gòu),爽
#include "stdio.h"
struct Tree{
int father;
int child;
int brother;
int TakeParty;
int Not;
int Max() {
return TakeParty > Not ? TakeParty : Not;
}
void init() {
father = child = brother = Not = 0;
}
}tree[6001];
void dfs(int idx ) {
int child;
child = tree[idx].child;
while(child) {
dfs(child);
tree[idx].TakeParty += tree[child].Not;
tree[idx].Not += tree[child].Max();
child = tree[child].brother;
}
}
int main() {
int n,i,a,b;
while(scanf("%d",&n) == 1) {
for(i =1 ; i <= n ; i ++) {
scanf("%d",&tree[i].TakeParty);
tree[i].init();
}
while(scanf("%d%d",&a,&b),a+b) {
tree[a].father = b;
tree[a].brother = tree[b].child;
tree[b].child = a;
}
for(i = 1 ; i <= n ; i ++) {
if(!tree[i].father) {
dfs(i);
printf("%d\n",tree[i].Max());
break;
}
}
}
return 0;
}
struct Tree{
int father;
int child;
int brother;
int TakeParty;
int Not;
int Max() {
return TakeParty > Not ? TakeParty : Not;
}
void init() {
father = child = brother = Not = 0;
}
}tree[6001];
void dfs(int idx ) {
int child;
child = tree[idx].child;
while(child) {
dfs(child);
tree[idx].TakeParty += tree[child].Not;
tree[idx].Not += tree[child].Max();
child = tree[child].brother;
}
}
int main() {
int n,i,a,b;
while(scanf("%d",&n) == 1) {
for(i =1 ; i <= n ; i ++) {
scanf("%d",&tree[i].TakeParty);
tree[i].init();
}
while(scanf("%d%d",&a,&b),a+b) {
tree[a].father = b;
tree[a].brother = tree[b].child;
tree[b].child = a;
}
for(i = 1 ; i <= n ; i ++) {
if(!tree[i].father) {
dfs(i);
printf("%d\n",tree[i].Max());
break;
}
}
}
return 0;
}


