zoukankan      html  css  js  c++  java
  • hdu 1520 Anniversary party

    题意

    某人要开一个聚会,每个人都有一个自己的交际评分,但是他们都不想和自己的直接上司在一起,那样会不开心,所以只让一部分人来,希望你能找出评分最大的方案。

    解析:

    关于上司下级的事情,就会涉及一点并查集,不过这题和并查集没有太大关系,需要建树来维系他们之间的关系,然后用树状dp来写,状态转移方程式为dp[i][0]+=max(dp[j][1],dp[i][0]),dp[i][1]+=dp[j][0];i表示父节点,j为子节点,0的意思是i或j没有出席m,1表示i或j出席了,也就是如果父节点没有出席,子节点可以出席也可以不出席,如果父节点出席了,子节点一定不能出席。

    代码:

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <algorithm>
    #include <queue>
    #include <vector>
    using namespace std;
    #define N 6005
    #define oo 0x3f3f3f3f
    vector<int>G[N];
    int n,dp[N][2],father[N];
    void dfs(int root)
    {
        for(int i=0;i<G[root].size();i++)
        {
            dfs(G[root][i]);
        } 
        for(int i=0;i<G[root].size();i++)
        {
            dp[root][0]+=max(dp[G[root][i]][0],dp[G[root][i]][1]);
            dp[root][1]+=dp[G[root][i]][0];
        }
    }
    int main()
    {
        int u,v;
        while(~scanf("%d",&n))
        {
            memset(father,-1,sizeof(father));
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&dp[i][1]);
                G[i].clear();
            }
            while(scanf("%d%d",&u,&v)&&(u+v))
            {
                father[u]=v;
                G[v].push_back(u);
            }
            int root=1;
            while(father[root]!=-1)
            root=father[root];
            dfs(root);
            printf("%d
    ",max(dp[root][1],dp[root][0]));
        }
    }
  • 相关阅读:
    Noip2015总结
    BZOJ2457 BeiJing2011 双端队列
    Noip模拟考第三题——饥饿游戏
    HDU 2196 求树上所有点能到达的最远距离
    O(V*n)的多重背包问题
    Noip2008双栈排序
    USACO 4.1.2 栅栏的木料
    字符串专题
    网络流24题刷题记录
    解模线性方程组 非互质中国剩余定理
  • 原文地址:https://www.cnblogs.com/shanshuiyouxiangfeng/p/9023638.html
Copyright © 2011-2022 走看看