算法: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.