zoukankan      html  css  js  c++  java
  • 1380 没有上司的舞会

    1380 没有上司的舞会

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 钻石 Diamond
     
     
     
    题目描述 Description

          Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。

    输入描述 Input Description

    第一行一个整数N。(1<=N<=6000)
    接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
    接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
    最后一行输入0,0。

    输出描述 Output Description

    输出最大的快乐指数。

    样例输入 Sample Input

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

    样例输出 Sample Output

    5

    数据范围及提示 Data Size & Hint

    各个测试点1s

    分类标签 Tags 

    思路分析:

    题目简化版 (思路一样)

    例题代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<vector>
     4 #define N 55000
     5 using namespace std;
     6 int f[N][2],fa[N],n;
     7 vector<int> v[N];
     8 void dp(int x)
     9 {
    10     for(int j=0;j<v[x].size();j++){
    11         int i=v[x][j];
    12         dp(i);
    13         f[x][0]+=max(f[i][0],f[i][1]);
    14         f[x][1]+=f[i][0];
    15     }
    16     f[x][1]++;
    17 }
    18 int main()
    19 {
    20     scanf("%d",&n);
    21     for(int i=1,x,y;i<n;i++){
    22           scanf("%d%d",&x,&y);
    23           fa[x]=y;
    24           v[y].push_back(x);
    25     }
    26     for(int i=1;i<=n;i++)
    27         if(fa[i]==0){
    28             dp(i);
    29             printf("%d
    ",max(f[i][0],f[i][1]));
    30             return 0;
    31         }
    32 }

    就是树型dp板子

    1380 没有上司的舞会代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<vector>
     4 #define N 55000
     5 using namespace std;
     6 int f[N][2],fa[N],a[N],n,x,y;
     7 vector<int> v[N];
     8 void dp(int x)
     9 {
    10     for(int j=0;j<v[x].size();j++){//循环 与x有多少条边相连  次 
    11         int i=v[x][j];//x的某一个儿子 
    12         dp(i);//递归到最底层 
    13         f[x][0]+=max(f[i][0],f[i][1]);//如果x不选,下层可以选 也可以不选 
    14         f[x][1]+=f[i][0];//如果x选,下层一定不能选
    15     }
    16     f[x][1]+=a[x];//如果x选,把本身加上 
    17 }
    18 int main()
    19 {
    20     scanf("%d",&n);
    21     for(int i=1;i<=n;i++)
    22       scanf("%d",a+i); 
    23     while(scanf("%d%d",&x,&y)==2&&x&&y){
    24           fa[x]=y;//x的爹是y 
    25           v[y].push_back(x);//v[y(父亲编号)][0-边个数(编表)]=x(儿子编号); 
    26     }
    27     for(int i=1;i<=n;i++)
    28         if(fa[i]==0){//找到根 
    29             dp(i);
    30             printf("%d
    ",max(f[i][0],f[i][1]));//根可能有多个儿子,选不选根取最优 
    31             return 0;
    32         }
    33 }
  • 相关阅读:
    C#异常小知识
    Cisco路由器配置学习-ip accounting
    Sublime Text 3预览Markdown
    什么是permit-inside功能
    锐捷双出口
    思科双出口+策略路由+NAT
    github常见操作和常见错误
    网易注册页面知识点
    java,xml等注释删除,正则表达式使用123
    简单多线程是否安全判断
  • 原文地址:https://www.cnblogs.com/shenben/p/5490973.html
Copyright © 2011-2022 走看看