您的位置:首页 > 其它

没有上司的晚会 树形DP

2016-05-13 20:15 309 查看
题意/Description:

Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。 



读入/Input:

第一行一个整数N。(1<=N<=6000) 
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127) 
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。 
最后一行输入0,0。



输出/Output:

输出最大的快乐指数。



题解/solution:

     根据题目给出的矛盾关系写出动规方程:

     T[i]表示不邀请i,以i为根的子树所获得的最大值

     F[i]表示邀请i,以i为根的子树所获得的最大值
     转移如下:


inc(t[v],f[son[d[v]]]);
inc(f[v],max(t[son[d[v]]],f[son[d[v]]]));




代码/Code:

var
v:array [0..6001] of boolean;
t,f,d,son,ls:array [0..6001] of longint;
n,tt:longint;
function max(o,p:longint):longint;
begin
if o>p then max:=o
else max:=p;
end;

procedure dfs(v:word);
begin
while d[v]>0 do
begin
dfs(son[d[v]]);
inc(t[v],f[son[d[v]]]);
inc(f[v],max(t[son[d[v]]],f[son[d[v]]]));
d[v]:=ls[d[v]];
end;
end;

procedure init;
var
i,x,y:longint;
begin
read(n);
for i:=1 to n do read(t[i]);
fillchar(v,sizeof(v),1);
tt:=n*(n+1) div 2;
for i:=1 to n-1 do
begin
read(x,y);
son[i]:=x; ls[i]:=d[y];
d[y]:=i;
if v[x] then begin dec(tt,x); v[x]:=false; end;
end;
end;

begin
init;
dfs(tt);
writeln(max(t[tt],f[tt]));
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息