URAL-1039 Anniversary Party---树形DP入门题

题目链接:

https://cn.vjudge.net/problem/URAL-1039

题目大意:

开一个party,每个员工都有一个欢乐值,只有是上司和下属不同时存在时才能欢乐,问怎样安排能有最大的欢乐值。

解题思路:

首先建立上司下属的树形结构,进行树形DP

dp[i][0]表示第i人不参加聚会时,以i为根节点的子树的最大欢乐值

dp[i][1]表示第i人参加聚会时,以i为根节点的子树的最大欢乐值

答案就为max(dp[root][0], dp[root][1])

根据边找到root节点

递推方程:

dp[i][0] = sum(max(dp[son][0], dp[son][1]))第i节点不去,它的儿子可以去,也可以不去

dp[i][1] = a[x] + sum(dp[son][0])    i节点去,那么它的儿子一定不可以去

用dfs来更新dp

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e4 + 10;
 4 vector<int>Map[maxn];
 5 int dp[maxn][2], a[maxn], father[maxn];
 6 void dfs(int x)
 7 {
 8     dp[x][1] = a[x];
 9     for(int i = 0; i < Map[x].size(); i++)
10     {
11         int son = Map[x][i];
12         dfs(son);
13         dp[x][0] = max(dp[x][0] + dp[son][1], dp[x][0] + dp[son][0]);
14         dp[x][1] = dp[x][1] + dp[son][0];
15     }
16     //cout<<x<<dp[x][0]<<dp[x][1]<<endl;
17 }
18 int main()
19 {
20     int n;
21     while(cin >> n)
22     {
23         memset(dp, 0, sizeof(dp));
24         for(int i = 1; i <= n; i++)
25         {
26             scanf("%d", &a[i]);
27             father[i] = -1;
28             Map[i].clear();
29         }
30         int u, v;
31         while(scanf("%d%d", &u, &v) != EOF)
32         {
33             if(!u && !v)break;
34             Map[v].push_back(u);
35             father[u] = v;
36         }
37         int root = 1;
38         while(father[root] != -1)
39         {
40             root = father[root];
41         }
42         dfs(root);
43         cout<<max(dp[root][0], dp[root][1])<<endl;
44     }
45     return 0;
46 }

原文地址:https://www.cnblogs.com/fzl194/p/9320609.html

时间: 2024-07-31 14:21:50

URAL-1039 Anniversary Party---树形DP入门题的相关文章

URAL 1039 Anniversary Party 树形DP 水题

1039. Anniversary Party Time limit: 0.5 secondMemory limit: 8 MB Background The president of the Ural State University is going to make an 80'th Anniversary party. The university has a hierarchical structure of employees; that is, the supervisor rela

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

[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 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个节点其他由新

POJ 2342 树形DP入门题

有一个大学的庆典晚会,想邀请一些在大学任职的人来参加,每个人有自己的搞笑值,但是现在遇到一个问题就是如果两个人之间有直接的上下级关系,那么他们中只能有一个来参加,求请来一部分人之后,搞笑值的最大是多少. 树形DP入门题. DP部分: dp[i][0]表示职员i不来参加party,以i为根的子树的最大搞笑值, dp[i][1]表示职员i来参加party,以i为根的子树的最大搞笑值. 转移方程: dp[cur][1]+=dp[next][0]; dp[cur][0]+=Max(dp[next][1]

POJ 2342 &amp;&amp;HDU 1520 Anniversary party 树形DP 水题

一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点)都不能被邀请 2.每一个员工都有一个兴奋值,在满足1的条件下,要使得邀请来的员工的兴奋值最高 输出最高的兴奋值. 简单的树形DP dp[i][1]:表示以i为根的子树,邀请节点i的最大兴奋值 dp[i][0]:表示以i为根的子树,不邀请节点i的最大兴奋值 先根据入度找出整棵树的根节点, 然后一次DF

[ACM] POJ 2342 Anniversary party (树形DP入门题)

Anniversary party Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4410   Accepted: 2496 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

HDU1520 Anniversary party(树形dp入门题)

题意: 给定一棵关系树,每个节点有个权值,子节点和父节点不能同时选,问最后能选的最大价值是多少? 思路: dp[i][1]表示选,dp[i][0]表示不选 则状态转移方程为: dp[i][1]+=dp[j][0]; dp[i][0]+=max(dp[j][1],dp[j][0]); AC代码: #include <iostream> #include <cstdio> #include <cstring> #include <string> #include