HDU-1520 树形dp

Problem 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 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 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
————————————————————————————————————————————————————————————
这道题不难……在比赛的时候基本的思路都想出来了,但是之前没有做过这类题,思路比较迟钝,不敢下手……结果上手知道怎么做以后63行解决……嘛……算是被dp这个名头给吓住的典例吧。
————————————————————————————————————————————————————————————
  首先说一下题意,就是说这道题有n个人,每个人都有自己的娱乐度,但是呢,有些人是其中一些人的上司,在这种场合会很尴尬,所以不能同时出现。上手的时候最容易的犯得错误就是想当然的直接用一层隔着一层来直接讨论,但是对于同样一层,可以不选,即对于1,2,3,4层,可以从1开始,略过2层,因为说不定1和4的值很高……嘛,这个自己理解吧。
  然后呢,既然不能简单的讨论,也就是说这个要做一个选和不选的选择,选的话,那么对于所有的孩子,取其不在的时候的最大值,如果不选的话,那孩子来不来要看其娱乐度总和到底是来的大还是不来的大,dp公式就是:
dp[i][0]+=max(dp[child-ith][0],dp[child-ith][1]) dp[i][1]+=dp[child-ith][0](对所有的孩子都过一遍)
上述过程从底向上来一遍就好了
————————————————————————————————————————————————————————————
#include<stdio.h>#include<string.h>#include<iostream>#include<vector>#include<algorithm>#include<string>#include<queue>#include<climits>#include<map>#include<stack>#include<list>#define file_in freopen("input.txt","r",stdin)#define MAX 8000#define HASH 100019using namespace std;#define ll long long#define FF(x,y) for(int i=x;i<y;i++)struct node {    int index;    vector<int>child;};vector<node>sto; int dp[MAX][2];void dfs(int index){    for (int i = 0; i < sto[index].child.size(); i++)//其实这里应该这么写    {        dfs(sto[index].child[i]);        dp[index][0] += max(dp[sto[index].child[i]][0], dp[sto[index].child[i]][1]);//<-delete        dp[index][1] += dp[sto[index].child[i]][0];//<-delete    }//就是把孩子都处理一边    //for (int i = 0; i < sto[index].child.size(); i++)    //{    //    dp[index][0] += max(dp[sto[index].child[i]][0], dp[sto[index].child[i]][1]);//然后全部相加一边,得到正解    //    dp[index][1] += dp[sto[index].child[i]][0];    //}}int main() { int num;    while (scanf("%d", &num) != EOF)    {        sto.clear();        sto.resize(num + 1);        for (int i = 1; i <= num; i++)        {            scanf("%d", &dp[i][1]);            dp[i][0] = 0;        }        int to, from;        map<int, int>M;        while (1)        {            scanf("%d %d", &to, &from);            if (to == 0)break;            sto[from].child.push_back(to);            M[to] = from;        }        int  root;        for (int i = 1; i <= num; i++)        {            if (M.find(i) == M.end())root = i;        }        dfs(root);        cout << max(dp[root][0], dp[root][1]) << endl;    } }/*711111111 32 36 47 44 53 50 0*/
时间: 2024-10-23 02:56:55

HDU-1520 树形dp的相关文章

HDU 1520 树形dp裸题

1.HDU 1520  Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define max(a,b) a>b?a:b using nam

hdu--1520--树形dp&lt;写起来就是深搜啊&gt;

我肯定还没怎么理解树形dp啊...为什么写下去 就感觉是多了个状态转移方程的深搜呢?或者因为树形dp是依托在树这个数据结构上所进行的 所以是这样的? 这题 被很多人 当做树形dp的入门题 的确.... 如果 u 是 v 的前驱即父母 那么 dp[u][0] += max( dp[v][1] , dp[v][0] ) 0表示u不包括在内 1在内 dp[u[[1] += dp[v][0] 不太难写 还好这个 主要是 每个树形dp都要找出根结点 因为数据很宽松 我直接用了vector来写 1 #inc

poj 2342 &amp;&amp; hdu 1520 树形dp

题意:有n个人,接下来n行是n个人的价值,再接下来n行给出l,k说的是l的上司是k,这里注意l与k是不能同时出现的 链接:点我 dp[i][1] += dp[j][0], dp[i][0] += max{dp[j][0],dp[j][1]};其中j为i的孩子节点. 第二次做感觉已经很水了 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #i

hdu 4123 树形DP+RMQ

http://acm.hdu.edu.cn/showproblem.php?pid=4123 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads in his village. Each road connects two houses,

hdu 1250 树形DP

Anniversary party Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-27) Description There is going to be a party to celebrate the 80-th Anniversary of the Ural St

hdu 4276(树形dp)

题意:带权树上有起点终点每个点上有宝藏,一个人只有T分钟要从起点到重点,问你最多能收集多少宝藏. 思路:树形dp,首先判断能不能走到终点,然后把路径上的边权变为0时间减去所有边权.dp[v][j]表示从v出发回到v话费j分钟最多能收集到的宝藏. dp[v][j] = max(dp[v][j], dp[x][k] + dp[v][j-k-2*val]); 被G++卡了好长时间,换成c++就过了. 代码如下: 1 #include <stdio.h> 2 #include <string.h

hdu 5148 树形dp+分组背包问题

http://acm.hdu.edu.cn/showproblem.php?pid=5148 Problem Description Long long ago,there is a knight called JayYe.He lives in a small country.This country is made up of n cities connected by n-1 roads(that means it's a tree).The king wants to reward Ja

HDU 2553 N皇后问题(递归深搜)

N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8525    Accepted Submission(s): 3802 Problem Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上. 你的任务是,对于给定的N,求

hdu 1011 树形dp+背包

题意:有n个房间结构可看成一棵树,有m个士兵,从1号房间开始让士兵向相邻的房间出发,每个房间有一定的敌人,每个士兵可以对抗20个敌人,士兵在某个房间对抗敌人使无法走开,同时有一个价值,问你花费这m个士兵可以得到的最大价值是多少 分析:树形dp,对于点u,dp[u][j]表示以u为根的树消耗j个士兵得到的最大值,dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[son][k]+val[u]) 注意是无向图,vis位置不能随便放,且注意dp不能直接+val,因为这样根节点就加不

hdu 3586 树形dp+二分

题目大意:给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵 树,每条边都有一个权值cost表示破坏这条边的费用,叶子节点为前线.现要切断前线和司令部的联系,每次切断边的费用不能超过上限limit,问切断所 有前线与司令部联系所花费的总费用少于m时的最小limit.1<=n<=1000,1<=m<=100万 题目要问的是最小的最大限制,必然二分答案 然后对于每一个值,树形DP判定是否可行 dp[i]表示要切断以i为根的其它所有子树的最小代价. 其中设定叶子结点的代价为无穷大