Anniversary party(树形DP入门)

Anniversary party

HDU - 1520

There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure of employees. It means that the supervisor relation forms a tree rooted at the rector V. E. Tretyakov. In order to make the party funny for every one, the rector does not want both an employee and his or her immediate supervisor to be present. The personnel office has evaluated conviviality of each employee, so everyone has some number (rating) attached to him or her. Your task is to make a list of guests with the maximal possible sum of guests‘ conviviality ratings.

InputEmployees are numbered from 1 to N. A first line of input contains a number N. 1 <= N <= 6 000. Each of the subsequent N lines contains the conviviality rating of the corresponding employee. Conviviality rating is an integer number in a range from -128 to 127. After that go T lines that describe a supervisor relation tree. Each line of the tree specification has the form: 
L K 
It means that the K-th employee is an immediate supervisor of the L-th employee. Input is ended with the line 
0 0OutputOutput should contain the maximal sum of guests‘ ratings. 
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题意:多组输入,每组输入的第一行一个N代表N个人,接下来N行每行一个数代表如果这个人参加party的欢乐值,接下来许多行,每行两个数u,v 表示v是u的直接上属。举行一个party,如果邀请了这个人的直接上司就不能邀请这个人,要求最后总的欢乐值最大,问欢乐值最大为多少。思路:  开一个二维dp dp[x][0]代表没有邀请x的最大欢乐值、
         dp[x][1]代表邀请了x的最大欢乐值。初始化dp[x][0]均为0 dp[x][1]为a[x]。dfs从树根遍历这棵树。具体看代码
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #include<algorithm>
 6 using namespace std;
 7 const int maxn=6010;
 8 vector<int>v[maxn];
 9 int dp[maxn][2],in[maxn],x,y;
10 int n,vis[maxn];
11 int a[maxn];
12 void dfs(int t)
13 {
14     dp[t][0]=0;        //dp数组的初始化。
15     dp[t][1]=a[t];
16     vis[t]=1;        //vis数组的意义如同记忆化搜索,如果这个叶子节点已经同时是其他节点的叶子节点,那么它已经被访问过,dp值已经更新了,不用再往下搜,因为下面都已经被搜过了,直接拿来用就行。
17     for(int i=0;i<v[t].size();i++)
18     {
19         int to=v[t][i];
20         if(vis[to])    //这个题数据比较水,如果不加vis数组也能过,但是时间会长。
21             continue;
22         dfs(to);
23         dp[t][0]+=max(dp[to][0],dp[to][1]);//如果不邀请t,那么就可以邀请他的直系下属
24         dp[t][1]+=dp[to][0];               //如果邀请t,那么久不能邀请他的直系下属
25     }
26     return ;
27 }
28 int main()
29 {
30     while(~scanf("%d",&n))
31     {
32         for(int i=1;i<=n;i++)
33             v[i].clear();
34         memset(in,0,sizeof(in));
35         memset(dp,0,sizeof(dp));
36         for(int i=1;i<=n;i++)
37         {
38             scanf("%d",&a[i]);
39         }
40         while(~scanf("%d%d",&x,&y)&&(x+y))
41         {
42             v[y].push_back(x);
43             in[x]++;
44         }
45         memset(vis,0,sizeof(vis));
46         for(int i=1;i<=n;i++)
47         {
48             if(!in[i])
49             {
50                 dfs(i);
51                 printf("%d\n",max(dp[i][0],dp[i][1]));
52                 break;
53             }
54         }
55     }
56 }

原文地址:https://www.cnblogs.com/1013star/p/9941532.html

时间: 2024-10-21 08:50:04

Anniversary party(树形DP入门)的相关文章

[poj2342]Anniversary party树形dp入门

题意:选出不含直接上下司关系的最大价值. 解题关键:树形dp入门题,注意怎么找出根节点,运用了并查集的思想. 转移方程:dp[i][1]+=dp[j][0];/i是j的子树 dp[i][0]+=max(dp[j][0],dp[j][1]); 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<iostream> 6

POJ 2342 Anniversary party (树形dp 入门题)

Anniversary party Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4810   Accepted: 2724 Description There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure

hdu oj 1520 Anniversary party(树形dp入门)

Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6990    Accepted Submission(s): 3104 Problem Description There is going to be a party to celebrate the 80-th Anniversary of the

POJ 2342 Anniversary party 树形dp入门

http://poj.org/problem?id=2342 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大. 对于每一个人,都有两种情况,选,或者不选.然后选了后,他的下属就只能不选了,如果它不选,下属可能选或者不选. 这样用dfs + 记忆化搜索,就好了 每次搜索,就是要求以第cur个节点为根的子树中,其中第cur个节点的状态是s

poj 2324 Anniversary party(树形DP)

/*poj 2324 Anniversary party(树形DP) ---用dp[i][1]表示以i为根的子树节点i要去的最大欢乐值,用dp[i][0]表示以i为根节点的子树i不去时的最大欢乐值, ---于是当i去时,i的所有儿子都不能去:dp[i][1]=sum(dp[j][0])+a[i],其中j是i的儿子节点. ---当i不去时,i的儿子可去也可不去:dp[i][0]=sum(max(dp[j][0],dp[j][1])),j是i的儿子节点 ---边界条件:当i时叶子节点时,dp[i][

hdu-1561 The more, The Better (树形dp入门,有依赖的背包问题

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4954    Accepted Submission(s): 2922 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝

POJ 3342 树形DP入门题

题目意思和POJ2342一样,只是多加了一个条件,如果最大方案数唯一,输出Yes,不唯一输出No dp的是时候多加一个变量记录答案是否唯一即可 #include "stdio.h" #include "string.h" #include "vector" using namespace std; struct node { int fa; vector<int>child; }data[210]; struct comp { int

POJ 1947 树形DP入门题

给出N个点,N-1个关系,建出树形图,问最少减去几个边能得到节点数为P的树.典型树形DP题 dp[cur][j] :记录cur结点,要得到一棵j个节点的子树去掉的最少边数 转移方程用的背包的思想 对当前树的每一个子树进行计算 砍掉此子树:   dp[cur][j]=dp[cur][j]+1; 不砍掉:           for (l=0;l<=j;l++)  dp[cur][j]=Min(dp[cur][j],dp[cur][l]+dp[next][j-l]); 枚举从该树中留l个节点其他由新

树形dp入门之poj 2342

题目:poj2342Anniversary party 题意:话说一个公司的一些然要去参加一个party,每个人有一个愉悦值,而如果某个人的直接上司在场的话会非常扫兴,所以避免这样的安排,问给出n个人,每个人的愉悦值以及他们的上司所属关系,问你让那些人去可以让总的愉悦值最大,并求出这个值. 分析:树形dp入门题目,这个公司的人事关系可以根据给出的数据得到一个树,最上面的是最高层,往下依次,我们要做的就是在树的节点处进行dp. 用dp[i][0]表示当前i这个人不选,dp[i][1]表示当前i这个