题目描述 Description
经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动。艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向一个展览室。Peer知道每个展室里藏画的数量,并且他精确测量了通过每条走廊的时间。由于经验老到,他拿下一幅画需要5秒的时间。你的任务是编一个程序,计算在警察赶来之前,他最多能偷到多少幅画。

题目描述 Description
输入输出样例 Sample input/output
输入样例:
60
7 0 8 0 3 1 14 2 10 0 12 4 6 2
输出样例:
2
给出的序列是一个深搜的顺序,是一个树的结构,满足无后效性,能够用DP来解决。
由于题目给出的数据很难记录叶子节点,采用指针记录。
f[root,t_now]:=max{f[left,k]+f[right,t_now-2*t-k]} (0<=k<=t_now)
采用用根到叶子的顺序。
Peer Brelstet需要进去再回来,所以提前将每条边的时耗*2;
在警察来之间离开:将警察的时间-1
code:
type tree=^point;
point=record
s,t:longint;
left,right:tree;
f:array[0..10000]of longint;
end;
var tt:longint;
r:tree;
procedure maketree(x:tree);
var i,j,k,a,b:longint;
begin read(x^.t,x^.s);
x^.t:=x^.t*2;
if x^.s<>0
then begin x^.left:=nil;
x^.right:=nil;
exit;
end
else begin new(x^.left);
new(x^.right);
maketree(x^.left);
maketree(x^.right);
end;
end;
procedure calc(x:tree;now:longint);
var i,j,k:longint;
begin with x^ do
begin fillchar(f,sizeof(f),0);
if now<=t
then exit;
if s>0
then begin for i:=t to now do
begin k:=(i-t) div 5;
if k<s
then f[i]:=k
else f[i]:=s;
end;
end
else begin calc(left,now-t);
calc(right,now-t);
for i:=t to now do
for k:=0 to i-t do
begin j:=left^.f[k]+right^.f[i-t-k];
if f[i]<j
then f[i]:=j;
end;
end;
end;
end;
begin readln(tt);
new(r);
maketree(r);//深搜建树
calc(r,tt);//dp
writeln(r^.f[tt]);
end.
原文:http://www.cnblogs.com/spiderKK/p/4881780.html