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 ...
随机推荐
- 301 MovedPermanently 重定向
页面永久性移走(301重定向)是一种非常重要的“自动转向”技术. 301重定向可促进搜索引擎优化效果 从搜索引擎优化角度出发,301重定向是网址重定向最为可行的一种办法.当网站的域名发生变更后,搜索引 ...
- php统计目录大小
function dirSize($directroy) { $dir_size=0; $dir_handle = @opendir($directroy); if($dir_handle) { wh ...
- 数据库抽象层 pdo
一 . PDO的连接 $host = "localhost"; $dbname = "hejuntest"; $username = "root&qu ...
- django使用auth模块进行身份认证
https://docs.djangoproject.com/zh-hans/2.0/topics/auth/default/#authentication-in-web-requests djang ...
- python-webdriver库之Keys
在使用webdriver时,有些时候我们需要做一些键盘上特殊键的操作,例如backspace,ctrl,shift等,这个时候就需要用到webdriver.common.keys.Keys方法来进行 ...
- react.js学习之路一
今天新老大来了,我们要学习他使用的框架react.js,现在是两眼一抹黑,对于我这个前端菜鸟来说,是真正的重新开始,好了,不说那么多了,开始随便记录我的学习,之后再整理内容. (1)对于react来说 ...
- 【转】C#中的combobox里DropDownStyle
源地址:https://blog.csdn.net/cf643487053/article/details/54016822 C#中的combobox控件里DropDownStyle有三种选项 Sim ...
- CBV请求流程源码分析
一.CBV流程解析 urls.py urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^book/', views.BookView.as ...
- Java面向对象之内部类(匿名内部类)
一.基础概念 匿名内部类:简化书写的内部类.其实匿名内部类就是一个子类对象. 前提:内部类需要继承或者实现外部的类或者接口. 格式:new 父类或者接口(){定义子类的内容} 二.将内部类定义到局部的 ...
- linux操作之文本编辑器
1.文本编辑器的作用 编辑和修改系统中的那些以文本形式存在的文件(特别是各种配置文件),也可以用于 编写程序代码 2.linux下的常见编辑器 nano.Emacs.gedit.vim等 3.vim三 ...