noip2007守望着的逃离 2008.11.5
小结:
到每一秒的时候,有三种选择:1,原地不动,m+4;2.使用魔法m-10,s+10;3.步行
这里还用到了一个贪心的策略:只要魔法值>=10,就用魔法,而不是原地呆着。所以,就变成了两种选择:1.可以用魔法就用,不能永就原地呆着—魔法选择(我们把用魔法和不用魔法归为为一类)
2.步行—不性选择
为什么会有这样一个贪心策略呢?
T 1 2 3 | 4 5
10(用去)4 8 | 12 (此时就有可以用魔法了,所以,归到下一次的时间中)
用魔法 当m=10时,可用3s行走60m v1:=20m/s
用步行 17m/s
所以用魔法和原地不动就可以合为一种情况了
心得:1.遇到像这样选择不同的方式有不同的效率的题,就要讨论一下哪种方式更合算
2.有时dp也可以将几种情况合并
我的,省去了数组的:每一秒,只和前一秒有关,所以只用几下前一秒就行了
program escape;
const fin='escape.in';fout='escape.out';
var m,s,t,ti:longint;
ts,ms1,ms2:longint;
f1,f2:text;
begin
assign(f1,fin);reset(f1);
assign(f2,fout);rewrite(f2);
read(f1,m,s,t);
ms2:=m;ts:=0;ms1:=0;
for ti:=1 to t do
begin
if ms2>=10 then
begin ms1:=ms1+60;ms2:=ms2-10;end
else ms2:=ms2+4;
if ts+17>ms1 then ts:=ts+17 else ts:=ms1;
if ts>=s then
begin writeln(f2,'Yes');
writeln(f2,ti);
close(f1);close(f2);
halt;
end;
end;
writeln(f2,'No');
writeln(f2,ts);
close(f1);close(f2);
end.
标称:
var m,s,t,ti:longint;
ms:array[1..2,0..300000] of longint;
ts:array[0..300000] of longint;
begin
while not eof do
begin
readln(m,s,t);
ms[2,0]:=m;
ts[0]:=0;
for ti:=1 to t do {动态规划}
begin
if ms[2,ti-1]>=10 then {如果能使用闪烁,就是用}
begin
ms[1,ti]:=ms[1,ti-1]+60;
ms[2,ti]:=ms[2,ti-1]-10;
end
else
begin
ms[1,ti]:=ms[1,ti-1]; {恢复魔法值}
ms[2,ti]:=ms[2,ti-1]+4;
end;
if ts[ti-1]+17>ms[1,ti] then ts[ti]:=ts[ti-1]+17
else ts[ti]:=ms[1,ti]; {用魔法的步数小过步行,则选用步行}
if ts[ti]>=s then {如果顺利逃出,输出结果}
begin
writeln('Yes');
writeln(ti);
halt;
end;
end;
writeln('No'); {无法逃出,输出结果}
writeln(ts[t]);
end;
end.