首页 > 其他 > 详细

树形DP:“访问”美术馆

时间:2015-10-15 11:15:02      阅读:361      评论:0      收藏:0      [点我收藏+]
题目描述 Description
经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动。艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向一个展览室。Peer知道每个展室里藏画的数量,并且他精确测量了通过每条走廊的时间。由于经验老到,他拿下一幅画需要5秒的时间。你的任务是编一个程序,计算在警察赶来之前,他最多能偷到多少幅画。
技术分享
输入输出格式 Input/output
输入格式:
第1行是警察赶到的时间,以s为单位。第2行描述了艺术馆的结构,是一串非负整数,成对地出现:每一对的第一个数是走过一条走廊的时间,第2个数是它末端的藏画数量;如果第2个数是0,那么说明这条走廊分叉为两条另外的走廊。数据按照深度优先的次序给出,请看样例。
一个展室最多有20幅画。通过每个走廊的时间不超过20s。艺术馆最多有100个展室。警察赶到的时间在10min以内。
输出格式:
输出偷到的画的数量
 
输入输出样例 Sample input/output
样例测试点#1
输入样例: 
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.
 

树形DP:“访问”美术馆

原文:http://www.cnblogs.com/spiderKK/p/4881780.html

(0)
(1)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!