DP Intro - Tree POJ2342 Anniversary party
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 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.
Input
Employees 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 N – 1 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 0
Output
Output 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
Source
Ural State University Internal Contest October'2000 Students Session
题目链接:http://poj.org/problem?id=2342
题目大意:一棵树,每个节点有一个值,现在要从中选一些点,要求这些点值和最大并且每对儿子和父亲不能同时被选
题目分析:dp[i][0]和dp[i][1]分别表示不选和选第i个点时以i为子树根时子树值的和,则:
dp[fa[i]][1] += dp[i][0] 表示选i的父亲时,其值等于自身值加上不选i时的值
dp[fa[i]][0] += max(dp[i][1], dp[i][0]) 表示不选父亲时,则其值等于其儿子被选或没被选的值的最大值
#include
#include
#include
#include
using namespace std;
int const MAX = 6005;
int dp[MAX][2], val[MAX];
bool vis[MAX], flag[MAX];
vector vt[MAX]; void DFS(int fa)
{
vis[fa] = true;
dp[fa][1] = val[fa];
int sz = vt[fa].size();
for(int i = 0; i < sz; i++)
{
int son = vt[fa][i];
if(!vis[son])
{
DFS(son);
dp[fa][1] += dp[son][0];
dp[fa][0] += max(dp[son][1], dp[son][0]);
}
}
return;
} int main()
{
int n;
while(scanf("%d", &n) && n)
{
for(int i = 1; i <= n; i++)
vt[i].clear();
memset(flag, false, sizeof(flag));
memset(vis, false, sizeof(vis));
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; i++)
scanf("%d", &val[i]);
for(int i = 0; i < n - 1; i++)
{
int a, b;
scanf("%d %d", &a, &b);
vt[b].push_back(a);
flag[a] = true;
}
int root;
for(int i = 1; i <= n; i++) //n个点n-1条边,必然存在“入度”为0的点即树根
{
if(!flag[i])
{
root = i;
break;
}
}
DFS(root);
printf("%d\n", max(dp[root][1], dp[root][0]));
}
}
=============================================================================================
今天开始做老师给的专辑,打开DP专辑 A题 Rebuilding Roads 直接不会了,发现是树形DP,百度了下了该题,看了老半天看不懂,想死的冲动都有了~~~~
最后百度了下,树形DP入门,找到了 poj 2342 Anniversary party 先入门一下~
题意:
某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大。
思路:
任何一个点的取舍可以看作一种决策,那么状态就是在某个点取的时候或者不取的时候,以他为根的子树能有的最大活跃总值。分别可以用f[i,1]和f[i,0]表示第i个人来和不来。
当i来的时候,dp[i][1] += dp[j][0];//j为i的下属
当i不来的时候,dp[i][0] +=max(dp[j][1],dp[j][0]);//j为i的下属
以下代码参考:http://hi.baidu.com/saintlleo/blog/item/0606b3feb7026ad3b48f3111.html
//AC CODE:
- #include<iostream>
- #include<cmath>
- #include<algorithm>
- #include<vector>
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- #include<string>
- using namespace std;
- #define maxn 6005
- int n;
- int dp[maxn][2],father[maxn];//dp[i][0]0表示不去,dp[i][1]1表示去了
- bool visited[maxn];
- void tree_dp(int node)
- {
- int i;
- visited[node] = 1;
- for(i=1; i<=n; i++)
- {
- if(!visited[i]&&father[i] == node)//i为下属
- {
- tree_dp(i);//递归调用孩子结点,从叶子结点开始dp
- //关键
- dp[node][1] += dp[i][0];//上司来,下属不来
- dp[node][0] +=max(dp[i][1],dp[i][0]);//上司不来,下属来、不来
- }
- }
- }
- int main()
- {
- int i;
- int f,c,root;
- while(scanf("%d",&n)!=EOF)
- {
- memset(dp,0,sizeof(dp));
- memset(father,0,sizeof(father));
- memset(visited,0,sizeof(visited));
- for(i=1; i<=n; i++)
- {
- scanf("%d",&dp[i][1]);
- }
- root = 0;//记录父结点
- bool beg = 1;
- while (scanf("%d %d",&c,&f),c||f)
- {
- father[c] = f;
- if( root == c || beg )
- {
- root = f;
- }
- }
- while(father[root])//查找父结点
- root=father[root];
- tree_dp(root);
- int imax=max(dp[root][0],dp[root][1]);
- printf("%d\n",imax);
- }
- return 0;
- }
DP Intro - Tree POJ2342 Anniversary party的更多相关文章
- DP Intro - poj 2342 Anniversary party
今天开始做老师给的专辑,打开DP专辑 A题 Rebuilding Roads 直接不会了,发现是树形DP,百度了下了该题,看了老半天看不懂,想死的冲动都有了~~~~ 最后百度了下,树形DP入门,找到了 ...
- DP Intro - Tree DP Examples
因为上次比赛sb地把一道树形dp当费用流做了,受了点刺激,用一天时间稍微搞一下树形DP,今后再好好搞一下) 基于背包原理的树形DP poj 1947 Rebuilding Roads 题意:给你一棵树 ...
- DP Intro - Tree DP
二叉苹果树 题目 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点 ...
- poj2342 Anniversary party (树形dp)
poj2342 Anniversary party (树形dp) Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9128 ...
- [poj2342]Anniversary party_树形dp
Anniversary party poj-2342 题目大意:没有上司的舞会原题. 注释:n<=6000,-127<=val<=128. 想法:其实就是最大点独立集.我们介绍树形d ...
- POJ2342 Anniversary party(动态规划)(树形DP)
Anniversary party Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6635 Accepted: 3827 ...
- 树形dp poj2342 Anniversary party * 求最大价值
Description There is going to be a party to celebrate the 80-th Anniversary of the Ural State Univer ...
- poj2342 Anniversary party【树形dp】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316097.html ---by 墨染之樱花 [题目链接]http://poj.org/p ...
- [poj2342]Anniversary party树形dp入门
题意:选出不含直接上下司关系的最大价值. 解题关键:树形dp入门题,注意怎么找出根节点,运用了并查集的思想. 转移方程:dp[i][1]+=dp[j][0];/i是j的子树 dp[i][0]+=max ...
随机推荐
- 在Eclipse中连接SQL
原创 在Eclipse中连接SQL分为如下几个步骤: 1.加载驱动程序 2.创建连接对象 3.创建执行SQL语句的对象 4.执行SQL语句 5.关闭new出来的对象 1.加载驱动程序(以SQL为例) ...
- WC 代码统计 java
GitHub地址 项目需求 实现一个wc统计程序,可以对文本进行相关功能的统计与分析 基本功能 -c 统计字符数 -w 统计文件词数 -l 统计行数 扩展功能 -s 递归搜索目录下面的文件 -a 返回 ...
- DataGridView移动上下行
/// <summary> /// 移动行 /// </summary> /// <param name="i_UpFlag">移动标识,tru ...
- C# 可变参数
class Program { static void Main(string[] args) { //常规使用方法 Console.WriteLine(Add(, , , , , , , , })) ...
- [.net 多线程]SpinWait
<CLR via C#>读书笔记-线程同步(四) 混合线程同步构造简介 之前有用户模式构造和内核模式构造,前者快速,但耗费CPU:后者可以阻塞线程,但耗时.耗资源.因此.NET会有一些混合 ...
- 正则表达式回溯-导致CPU偏高
最近了解了下有关正则表达式回溯的内容,想想就写下来,方便自己. 正则表达式匹配算法是建立在正则表达式引擎的基础上的,目前有两种引擎:DFA(确定型有穷自动机)和NFA(不确定型有穷自动机).这两种引擎 ...
- C#中base的作用
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- 【[APIO/CTSC2007]动物园】状压DP
题目测评:https://www.luogu.org/problemnew/show/P3622 题目描述 新建的圆形动物园是亚太地区的骄傲.圆形动物园坐落于太平洋的一个小岛上,包含一大圈围栏,每个围 ...
- 如何修改git显示的用户名
我是这样试了一下,可以改: 输入修改用户名和邮箱: $git config --global user.email "tanteng@gmail.com" $git config ...
- Java程序员修炼之路
作者简介:王成委,CSDN知识库特邀编辑,Java高级工程师,熟悉Java编程语言和Oracle数据库.专注于高并发架构设计和大数据存储方向的研究. 我们为什么选择Java 大多数人选择Java可能只 ...