• CH5401 没有上司的舞会【树形DP】


    5401 没有上司的舞会 0x50「动态规划」例题

    描述

    Ural大学有N名职员,编号为1~N。他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。每个职员有一个快乐指数,用整数 H_i 给出,其中 1≤i≤N。现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。

    输入格式

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

    输出格式

    输出最大的快乐指数。

    样例输入

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

    样例输出

    5

    题意:

    有一棵树,表示的是上下隶属关系。这n个人的一部分人要去参加舞会,但是不希望和父亲节点一起参加。每个人有一个happy值。求最大的happy值之和。

    思路:

    对于每一个节点x,都有两种状态:1.参加舞会 2.不参加舞会

    如果x参加舞会,那么他的所有孩子都不能参加舞会

    如果x不参加舞会,那么他的孩子可以参加,也可以不参加。

    每一个节点x的最优解,都由他的孩子的最优解决定。

    用二维数组dp[i][0], dp[i][1]分别表示i节点不参加时的最大值和i节点参加时的最大值。

     1 //#include <bits/stdc++.h>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<stdio.h>
     6 #include<cstring>
     7 #include<vector>
     8 #include<map>
     9 
    10 #define inf 0x3f3f3f3f
    11 using namespace std;
    12 typedef long long LL;
    13 
    14 int n;
    15 const int maxn = 6005;
    16 int happy[maxn];
    17 vector<int>son[maxn];
    18 int dp[maxn][2];
    19 bool has_father[maxn];
    20 
    21 int dfs(int rt)
    22 {
    23     dp[rt][0] = 0;
    24     dp[rt][1] = happy[rt];
    25     for(int i = 0; i < son[rt].size(); i++){
    26         int y = son[rt][i];
    27         dfs(y);
    28         dp[rt][0] += max(dp[y][0], dp[y][1]);
    29         dp[rt][1] += dp[y][0];
    30     }
    31 }
    32 
    33 int main()
    34 {
    35     scanf("%d", &n);
    36     for(int i = 1; i <= n; i++){
    37         scanf("%d", &happy[i]);
    38     }
    39     for(int i = 1; i < n; i++){
    40         int x,y;
    41         scanf("%d%d", &x, &y);
    42         has_father[x] = true;
    43         son[y].push_back(x);
    44     }
    45     int root;
    46     for(int i = 1; i <= n; i++){
    47         if(!has_father[i]){
    48             root = i;
    49             break;
    50         }
    51     }
    52 
    53     dfs(root);
    54     int ans = max(dp[root][0], dp[root][1]);
    55     printf("%d
    ", ans);
    56     return 0;
    57 }
  • 相关阅读:
    Linux Shell系列教程之(十七) Shell文件包含
    Linux Shell系列教程之(十六) Shell输入输出重定向
    Linux Shell系列教程之(十五) Shell函数简介
    Linux Shell系列教程之(十四) Shell Select教程
    Linux Shell系列教程之(十三)Shell分支语句case … esac教程
    Linux Shell系列教程之(十二)Shell until循环
    Linux Shell系列教程
    算法系列:链表
    C++ 系列:Boost Thread 编程指南
    C++:多线程002
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9760282.html
Copyright © 2020-2023  润新知