树形DP,从字面上看,就是在树上DP。DP要有拓扑关系,在树上找拓扑关系,太麻烦,所以记忆化搜索实现。
有3种决策:
PARENT GO & SON STAY
PARENT STAY & SON ? (?=GO/STAY)
/*
* tyvj-1052
* mike-w
* 2011-11-8
* ------------
* 树形DP首题
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 6060
#define INF (9999999)
int h[SIZE], /* happy index */
f[SIZE]; /* father node */
int opt[SIZE][2];
int N;
/*
* 找到WA原因:老板不去,员工也可以不去...
*/
int search(int node,int flag) /* flag=0: node stays; flag=1: node goes */
{
if(opt[node][flag]!=-INF)
return opt[node][flag];
int i,tmp,tmp2;
opt[node][flag]=h[node]*flag;
for(i=1;i<=N;i++)
if(f[i]==node)
{
tmp=opt[node][flag]+search(i,!flag);
if(!flag)
{
tmp2=opt[node][flag]+search(i,flag);
if(tmp<tmp2) tmp=tmp2;
}
if(opt[node][flag]<tmp)
opt[node][flag]=tmp;
}
return opt[node][flag];
}
int main(void)
{
int i,j,k,l,tmp,ans;
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
#endif
scanf("%d",&N);
for(i=1;i<=N;i++)
scanf("%d",h+i);
for(i=2;i<=N;i++)
scanf("%d%d",&l,&k),f[l]=k;
ans=-INF;
for(i=1;i<=N;i++)
opt[i][0]=opt[i][1]=-INF;
for(i=1;i<=N;i++)
for(j=0;j<2;j++)
{
tmp=search(i,j);
if(tmp>ans)
ans=tmp;
}
printf("%d\n",ans);
return 0;
}