标签:
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