• 没有上司的舞会(luogu 1352)树形DP


    题目描述
    某大学有N个职员,编号为1~N。他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是呢,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。

    输入输出格式
    输入格式:
    第一行一个整数N。(1<=N<=6000)

    接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)

    接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。

    最后一行输入0 0

    输出格式:
    输出最大的快乐指数。


    输入样例          输出样例

    7              5
    1
    1
    1
    1
    1
    1
    1
    1 3
    2 3
    6 4
    7 4
    4 5
    3 5
    0 0


    今天真是幸运的一天,新学的树状DP一下A了,可以说是我学DP以来最稳的一次。可能是之前在B站上看了“正月点灯笼” 的DP教学,加上今天Xing学长的悉心教导,做这道题时行云流水。

    解析:

     树形DP这么命名,正是因为DP关系是呈树形的,依照样例,如图:

    • 用 indu[ ] 存每个节点的入度情况,然后找到入度为 0 的点(也就是根节点),标记上,作为dfs的起始
    • 用 hap[ ] 记录每个节点的开心值
    • 开一个 f[MX][2] , f[i][0] 表示不选 i 的最优情况,f[i][1] 表示选 i 的最优情况
    • 深搜下去,每搜一个节点,先把 f[from][1] 赋值为hap[from]
    1. 如果你选了上司,直系下属就不能选,但可以加上直系下属不选的最优 f[to][0] 来使得f[from][1] 最优
    2. 如果你不选上司,直系下属都可以选,但你选了不一定比不选好,所以 f[from][0]+=max(f[to][1],f[to][0])

     

    代码^-^

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    int f[6001][2],hap[6001],first[6001],indu[6001];
    
    struct Edge{
        int to,next;
    }edge[6001];
    
    int cnt,st;
    void add(int to,int from)
    {
        edge[++cnt].to=to;
        edge[cnt].next=first[from];
        first[from]=cnt;
        indu[to]++;
    }
    
    void dfs(int from)
    {
        f[from][1]=hap[from];
        for(int i=first[from];i;i=edge[i].next)
        {
            int to=edge[i].to;
            dfs(to);
            f[from][1]+=f[to][0];
            f[from][0]+=max(f[to][1],f[to][0]);
        }
    }
    
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
            scanf("%d",&hap[i]);
            int down,up;
        while(scanf("%d%d",&down,&up)!=EOF)
        {
            if(down==0 && up==0) break;
            add(down,up);
        }
        for(int i=1;i<=n;++i)
            if(indu[i]==0) {
                st=i;
                break;
            }
        dfs(st);
        printf("%d",max(f[st][1],f[st][0]));
        return 0;
    }
    从0到1很难,但从1到100很容易
  • 相关阅读:
    C# json转对象
    sit、qas、dev、pet
    vs professional 2019 离线安装包下载方法
    C# SHA512和Base64加解密方法
    C#获取客户端Ip工具类
    C#xml泛型序列化
    C#对象转换工具类
    C#记录日志到本地文件工具类
    05 Activity生命周期
    05 利用Appliction 传值Activity
  • 原文地址:https://www.cnblogs.com/qseer/p/9441866.html
Copyright © 2020-2023  润新知