标签:
Description
Input
Output
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
一个公司去参加宴会,要求去的人不能有直接领导关系,给出每一个人的欢乐值,和L K代表K是L的直接领导,问最大的欢乐值是多少。
将公司的关系建为一棵树,从最大的老板向下dfs
dp[i][0] 代表以编号为i的那个员工为根的一棵子树(不包含i)的最大欢乐值。
dp[i][1] 代表以编号为i的那个员工为根的一棵子树(包含i)的最大欢乐值。
那么得到状态转移方程假设j为i的下属
dp[i][0] = max( dp[j][0],dp[j][1] ) ;
dp[i][1] = max( dp[j][0] ) + c[i] ;
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; struct node{ int v ; int next ; }edge[10000]; int head[10000] , cnt ; int c[10000] ; int dp[10000][2] ; void add(int l,int k) { edge[cnt].v = l ; edge[cnt].next = head[k] ; head[k] = cnt++ ; } void dfs(int u) { if( head[u] == -1 ) { dp[u][0] = 0 ; dp[u][1] = c[u] ; return ; } int i , v ; for(i = head[u] , dp[u][1] = c[u] ; i != -1 ; i = edge[i].next) { v = edge[i].v ; dfs(v) ; dp[u][0] += max(dp[v][0],dp[v][1]) ; dp[u][1] += dp[v][0] ; } return ; } int main() { int n , i , j , l , k , num ; while( scanf("%d", &n) != EOF ) { memset(dp,0,sizeof(dp)) ; memset(head,-1,sizeof(head)) ; cnt = num = 0 ; for(i = 1 ; i <= n ; i++) { scanf("%d", &c[i]) ; num += i ; } while( scanf("%d %d", &l, &k) && (l+k != 0) ) { num -= l ; add(l,k) ; } dfs(num) ; printf("%d\n", max( dp[num][0],dp[num][1] ) ); } return 0 ; }
poj2342--hdu1520-- Anniversary party(树形DP练习1)
标签:
原文地址:http://blog.csdn.net/winddreams/article/details/42833545