HDU - 1520(Anniversary party)树形DP

题意:

公司要开一个舞会,邀请各阶层的职员来参加,每个职员来参加舞会时会给舞会增高快乐值(大小因人而异)。

但是如果一个职员的直属领导也来参加舞会,那么这个职员就不会去参加舞会。

(相当于一棵树,如果父亲在,儿子必定不在,但孙子可以在也可以不在)

题解: 

树形DP,转移方程:

dp[root][i] (i=0,1)表示当前结点root,1代表root在,0代表不在。

1. dp[root][1]+=dp[v][0]; 如果父亲在,儿子必定不在

2.dp[root][0]+=max(dp[v][0],dp[v][1]); 如果父亲不在,选取儿子最大值的状态。

 代码:

#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define clr(str,x) memset(str,x,sizeof(str))
#define FRER() freopen("in.txt","r",stdin);
#define FREW() freopen("out.txt","w",stdout);
#define MAX_INF 0x7fffffff
#define INF 0x3f3f3f3f
#define maxn 6010

typedef long long int ll;
using namespace std;
int n,dp[maxn][2];
bool in[maxn];
vector<int> G[maxn];
void dfs(int root)
{
    for(int i=0; i<G[root].size(); i++)
    {
        int v=G[root][i];
        dfs(v);
        dp[root][1]+=dp[v][0];
        dp[root][0]+=max(dp[v][0],dp[v][1]);
    }
}
int main()
{
    //FRER();
    //FREW();
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        clr(dp,0);
        clr(in,0);
        for(int i=0; i<maxn; i++)
            G[i].clear();
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&dp[i][1]);
        }
        int root=1;
        int u,v;
        while(cin>>u>>v&&(v+u))
        {
            G[v].push_back(u);
            in[u]=1;
        }
        for(int i=1; i<=n; i++)
        {
            if(in[i]==0)
                root=i;
        }
        dfs(root);
        cout<<max(dp[root][0],dp[root][1])<<endl;
    }

    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值