zoukankan      html  css  js  c++  java
  • poj2342 Anniversary party【树形dp】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316097.html   ---by 墨染之樱花

    【题目链接】http://poj.org/problem?id=2342

    【题目描述】一个企业有N个员工,每个人都有一个表示欢乐度的数值。现在要开一场party,不过这些员工里面有上下级关系,每个员工都不希望见到自己的直接上司,即每个员工都不能和直接上司同时出现。求这场party到场的人的总欢乐度的最大值

    【思路】最基础的树形dp,现根据上下级关系构成树状图森林,然后在每棵树上进行动态规划,dp[i][0]和dp[i][1]表示以i为根的子树分别在i不来和来的情况下的最大总欢乐度。显然有dp[i][1]=sum(dp[j][0])+a[i],dp[i][0]=sum(max(dp[j][0],dp[j][1])),其中j遍历i的所有儿子节点。最后只需求森林中所有根结点的max(dp[r][0],dp[r][1])的总和

    #include <iostream>
    #include <ios>
    #include <iomanip>
    #include <functional>
    #include <algorithm>
    #include <vector>
    #include <sstream>
    #include <list>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <string>
    #include <set>
    #include <map>
    #include <cstdio>
    #include <cstdlib>
    #include <cctype>
    #include <cmath>
    #include <cstring>
    #include <climits>
    using namespace std;
    #define XINF INT_MAX
    #define INF 1<<30
    #define MAXN 6000+10
    #define eps 1e-10
    #define zero(a) fabs(a)<eps
    #define sqr(a) ((a)*(a))
    #define MP(X,Y) make_pair(X,Y)
    #define PB(X) push_back(X)
    #define PF(X) push_front(X)
    #define REP(X,N) for(int X=0;X<N;X++)
    #define REP2(X,L,R) for(int X=L;X<=R;X++)
    #define DEP(X,R,L) for(int X=R;X>=L;X--)
    #define CLR(A,X) memset(A,X,sizeof(A))
    #define IT iterator
    #define PI  acos(-1.0)
    #define test puts("OK");
    #define _ ios_base::sync_with_stdio(0);cin.tie(0);
    typedef long long ll;
    typedef pair<int,int> PII;
    typedef priority_queue<int,vector<int>,greater<int> > PQI;
    typedef vector<PII> VII;
    typedef vector<int> VI;
    #define X first
    #define Y second
    
    VI G[MAXN];
    int num[MAXN];
    int par[MAXN];
    int dp[MAXN][2];
    int N;
    
    void dfs(int r)
    {
        if(G[r].size()==0)
        {
            dp[r][0]=0;
            dp[r][1]=num[r];
        }
        REP(i,G[r].size())
            dfs(G[r][i]);
        dp[r][0]=dp[r][1]=0;
        REP(i,G[r].size())
            dp[r][1]+=dp[G[r][i]][0];
        dp[r][1]+=num[r];
        REP(i,G[r].size())
            dp[r][0]+=max(dp[G[r][i]][0],dp[G[r][i]][1]);
    }
    
    int main()
    {_
        CLR(par,-1);
        scanf("%d",&N);
        REP(i,N)
            scanf("%d",&num[i]);
        int x,y;
        while(scanf("%d%d",&x,&y))
        {
            if(x==0 && y==0)
                break;
            x--;y--;
            par[x]=y;
            G[y].PB(x);
        }
        int tot=0;
        REP(i,N)
            if(par[i]==-1)
            {
                dfs(i);
                tot+=max(dp[i][0],dp[i][1]);
            }
        printf("%d
    ",tot);
        return 0;
    }
    View Code
  • 相关阅读:
    典型用户
    站立会议5
    站立会议4
    《构建之法》阅读笔记05-需求分析
    站立会议3
    编写Android程序Eclipse连不上手机。
    站立会议2
    站立会议1
    第七周学习进度
    shiro之 散列算法(加密算法)
  • 原文地址:https://www.cnblogs.com/KirisameMarisa/p/4316097.html
Copyright © 2011-2022 走看看