天堂的馈赠(Vijos1235)

算法:DP

分析:本题类似于IOI98的免费馅饼,注意这道题是刚好落在手里的才能算作被取到,因此一开始先处理出能不能被取到的情况。
      DP是一个还算简单的过程,因为每次最多只能走1步,因此只要模拟出三个状态来就可以了,f[i,j]表示i时刻到第j个格子能取到的最大价值。

program Vijos1235;

const
 maxw=500;
 maxt=3000;

var
 w,p,h,n,maxt1,tot,ans:longint;
 f,value:array [0..maxt,0..maxw] of longint;

procedure init;
var
 i,t,r,v,s,fint:longint;
begin
 tot:=0;
 readln(w,p,h,n);
 for i:=1 to n do
  begin
   readln(t,r,v,s);
   if h mod v=0 then
    begin
     fint:=t+(h div v)-1;
     value[fint,r]:=s;
     if fint>maxt1 then maxt1:=fint;
    end
   else inc(tot,s);
  end;
end;

function max(x,y:longint):longint;
begin
 if x>y then exit(x) else exit(y);
end;

procedure main;
var
 i,j:longint;
begin
 fillchar(f,sizeof(f),-$2F);
 f[1,p]:=value[1,p];
 ans:=f[1,p];
 for i:=2 to maxt1 do
  begin
   for j:=1 to w do
    begin
     if (f[i-1,j-1]=f[0,0]) and (f[i-1,j+1]=f[0,0]) and (f[i-1,j]=f[0,0]) then
      begin
       f[i,j]:=f[0,0];
       inc(tot,value[i,j]);
      end
     else
      begin
       f[i,j]:=max(f[i-1,j-1],max(f[i-1,j+1],f[i-1,j]))+value[i,j];
       if f[i,j]>ans then ans:=f[i,j];
      end;
    end;
  end;
end;

begin
 assign(input,'VJ1235.in'); reset(input);
 assign(output,'VJ1235.out'); rewrite(output);
 
 init;
 main;
 writeln(ans);
 writeln(tot);
 
 close(input); close(output);
end.


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值