HDU 1520 Anniversary party(树形DP)

题目链接:

1520 Anniversary party

思路:

1.题意:父亲和儿子不能一起出现,问能一起出现的所有结点值的最大值;
2.设dp[i][0]dp[i][0]dp[i][1]dp[i][1]分别是以ii为根的子树、ii结点出现和不出现时的结点值最大值,设sonson为结点ii的儿子,则有
dp[i][0]+=max{dp[son][0],dp[son][1]}dp[i][0]+=max{dp[son][0],dp[son][1]}
dp[i][1]=dp[son][0]dp[i][1]=dp[son][0]

代码:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=6000+5;
int n,val[maxn],par[maxn],dp[maxn][2];
vector<int> tree[maxn];
void dfs(int now){
    dp[now][0]=0; dp[now][1]=val[now];
    for(int son:tree[now]){
        dfs(son);
        dp[now][0]+=max(dp[son][0],dp[son][1]);
        dp[now][1]+=dp[son][0];
    }
}
void clear(){
    for(int i=1;i<=n;i++) par[i]=0,tree[i].clear();
}
int main(){
//  freopen("Sakura.txt","r",stdin);
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++) scanf("%d",val+i);
        int L,K;
        while(scanf("%d%d",&L,&K)){
            if(L==0&&K==0) break;
            tree[K].push_back(L);
            par[L]=K;
        }
        int root=1;
        while(par[root]) root=par[root];
        dfs(root);
        printf("%d
",max(dp[root][0],dp[root][1]));
        clear();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/yuhan-blog/p/12308721.html