[codevs1163]访问艺术馆

var
  len:array[1..400,1..400] of longint;
  number:array[1..2400] of longint;
  dp:array[1..400,0..600] of longint;
  s,i,x:longint;


function min(a,b:longint):longint;
begin
  if a<b then exit(a) else exit(b);
end;

procedure dfs(u:longint);
var
  i,j:longint;
begin
  if number[u]<>0 then exit;
  dfs(u*2); dfs(u*2+1);
  for i:=0 to number[u*2] do
    for j:=0 to number[u*2+1] do
      begin
       if (i=0)and(j<>0) then dp[u,j]:=min(dp[u,j],dp[u*2+1,j]+len[u,u*2+1]*2);
        if (j=0)and(i<>0) then dp[u,i]:=min(dp[u,i],dp[u*2,i]+len[u,u*2]*2);
        if (i<>0)and(j<>0) then dp[u,i+j]:=min(dp[u,i+j],dp[u*2,i]+len[u,u*2]*2+dp[u*2+1,j]+len[u,u*2+1]*2);
      end;
  number[u]:=number[u*2]+number[u*2+1];
end;
procedure build(u:longint);
var
  x,i:longint;
begin
  read(len[u,u*2],x);
  if x=0 then build(u*2) else
    begin
      for i:=1 to x do
        dp[u*2,i]:=i*5;
      number[u*2]:=x;
    end;
  read(len[u,u*2+1],x);
  if x=0 then build(u*2+1) else
    begin
      for i:=1 to x do
        dp[u*2+1,i]:=i*5;
     number[u*2+1]:=x;
   end;
end;

begin
  readln(s);
  fillchar(dp,sizeof(dp),$7f);
  read(i,x);
  s:=s-i*2;//这一部分是因为进入艺术馆有一条路,而这条路是不符合题目要求的,所以直接使s-需要的时间*2即可
  build(1);//建立这颗二叉树(我的代码可能不是最简的,请多多包涵)
  dfs(1);//树形DP
  for i:=number[1] downto 1 do
    if dp[1,i]<=s then
      begin
        write(i);
        exit;
      end;//求得最终答案
  write(0);
end.

 喜欢就收藏一下,vic私人qq:1064864324,加我一起讨论问题,一起进步^-^

posted @ 2015-09-29 09:02  ROLL-THE-FIRST  阅读(134)  评论(0编辑  收藏  举报