zoukankan      html  css  js  c++  java
  • 【洛谷 1352】没有上司的舞会

    题目描述

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

    第一行一个整数N。(1<=N<=6000)

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

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

    最后一行输入0 0

    输出格式:

    输出最大的快乐指数。

    输入输出样例
    输入样例#1: 复制

    7

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

    输出样例#1: 复制

    5

    (一年前写的DP嘿嘿嘿)
    Step1:本题是个入门级别的树形DP题目

    Step2:前情提要_本题有多组数据_下文中的爸爸就指代直系上属

    Step3:由题意知,爸爸和儿子只能同时去一个,因此可以得出转移方程:dp[m][1]=dp[i][0]。\m是i的父亲,1表示去,0表示不去\ dp[m][0]+=max(dp[i][1],dp[i][0])即如果父亲不去,则在儿子的去或不去最大收益中找最大值

    Step4:首先要找到这棵树的顶根{祖先},然后再从祖先DFS

    Step5:貌似没啥要说的了

    代码;

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=10005;
    int dp[N][5];  
    int fa[N],vis[N],n;
    void dfs(int m){
        vis[m]=1;//标记m已经访问 
        for(int i=1;i<=n;i++){
            if(vis[i]==0 && fa[i]==m){
                //如果此点还未访问而且m是i的直系领导(爸爸) 
                dfs(i); //dfs儿子的儿子 
                dp[m][0]+=max(dp[i][0],dp[i][1]);
                //m不去,取i去或不去的最大值 
                dp[m][1]+=dp[i][0];
                //m去,则i必不能去
            }
        }
    }
    void init(){
        memset(dp,0,sizeof(dp));//初始化dp 
        memset(fa,0,sizeof(fa));//初始化fa
        memset(vis,0,sizeof(vis));//初始化vis
    } 
    int main(){
        freopen("1352.in","r",stdin);
        freopen("1352.out","w",stdout);
        while(scanf("%d",&n)!=EOF){
            init();//初始化 
            for(int i=1;i<=n;i++)
                scanf("%d",&dp[i][1]);
            //dp[i][0/1]表示第i个人会不会去参加party
            //0则不去,1则去,只有当它去的时候才会加上这个开心值
            //所以直接把这个开心值存到dp[i][1]即可 
            int x,y,rt=1;//rt从第1个人开始寻找父亲 
            while(scanf("%d %d",&x,&y)!=EOF && x+y>0)
                fa[x]=y;//y是x的爸爸 
            while(fa[rt]!=0)//查找父结点(即下一个根在哪里) 
                rt=fa[rt];//搜索到最后的结果一定是这棵树的顶根 
            dfs(rt);//成功去搜索这棵树的顶根 
            int ans=max(dp[rt][0],dp[rt][1]);//选或不选的方案数中的最大值 
            printf("%d
    ",ans);
        }
        return 0;
    }
     
  • 相关阅读:
    第4月第1天 makefile automake
    第3月30天 UIImage imageWithContentsOfFile卡顿 Can't add self as subview MPMoviePlayerControlle rcrash
    第3月第27天 uitableviewcell复用
    learning uboot fstype command
    learning uboot part command
    linux command dialog
    linux command curl and sha256sum implement download verification package
    learning shell script prompt to run with superuser privileges (4)
    learning shell get script absolute path (3)
    learning shell args handing key=value example (2)
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11241676.html
Copyright © 2011-2022 走看看