守望者的逃离 pascal

最详细最清晰的思路
【问题描述】
恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变。守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上。为了杀死守望者,尤迪安开始对这个荒岛施咒,这座岛很快就会沉下去。到那时,岛上的所有人都会遇难。守望者的跑步速度为17m/s,以这样的速度是无法逃离荒岛的。庆幸的是守望者拥有闪烁法术,可在1s内移动60m,不过每次使用闪烁法术都会消耗魔法值10点。守望者的魔法值恢复的速度为4点/s,只有处在原地休息状态时才能恢复。
现在已知守望者的魔法初值M,他所在的初始位置与岛的出口之间的距离S,岛沉没的时间T。你的任务是写一个程序帮助守望者计算如何在最短的时间内逃离荒岛,若不能逃出,则输出守望者在剩下的时间内能走的最远距离。注意:守望者跑步、闪烁或休息活动均以秒(s)为单位,且每次活动的持续时间为整数秒。距离的单位为米(m)。
【输入格式】空格隔开的三个非负整数M, S, T。
【输出格式】 第1行为字符串“Yes”或“No”,即守望者是否能逃离荒岛。
第2行包含一个整数。第一行为“Yes"时表示守望者逃离荒岛的最短时间;第一行为“No”时表示守望者能走的最远距离。

这题可以用贪心做,也可以用动规做,我比较偏向贪心算法。
你想想,如果魔法值>=10,肯定用魔法,不用说
如果>=8并且剩余时间>=2,恢复魔法
当前剩余magic>=6 and 剩余time>=3,恢复
magic>=2 and time>=4,恢复
time>=7,恢复
其余情况走路,至于为什么,动笔算算,例如当magic=6时
如果回魔,3秒内走60米,不回,则走51米,不合算,而如果只剩2秒,那么直接走,因为不够回魔的。特别注明一下magic=0或1,要7秒,因为这种情况要经过2次跳跃才能翻盘。
这样可以求出一定时间内最多走的路程。
如果不够,则直接输出,如果够,则二分时间,查找最大的时间能逃离,输出。二分查找用上了。
program p1431;
var
m,s,t,dis,i,l,r,mid,m1:longint;
begin
readln(m,s,t);m1:=m;
dis:=0;
for i:=1 to t do
begin
if (m>=10) or (m>=6) and (t-i>=1) or
(m>=2) and (t-i>=2) or (t-i>=6) then
begin
if m>=10 then begin m:=m-10;dis:=dis+60;end else m:=m+4;
end
else dis:=dis+17;
end;
m:=m1;
if dis<s then begin writeln('No');writeln(dis);end
else
begin
writeln('Yes');
l:=1;r:=t;
while l<r do
begin
mid:=(l+r) div 2;
dis:=0;m1:=m;t:=mid;
for i:=1 to t do
begin
if (m>=10) or (m>=6) and (t-i>=1) or
(m>=2) and (t-i>=2) or (t-i>=6) then
begin
if m>=10 then begin m:=m-10;dis:=dis+60;end else m:=m+4;
end
else dis:=dis+17;
end;
m:=m1;
if dis>=s then r:=mid else l:=mid+1;
end;
writeln(l);
end;
end.
温馨提示:答案为网友推荐,仅供参考
第1个回答  2009-11-12
program escape(input,output);
var
m,s,t,ti:longint;
ms:array[1..2,0..300000] of longint;
ts:array[0..300000] of longint;
begin
assign(input,'escape.in');
assign(output,'escape.out');
reset(input);
rewrite(output);
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);
close(input);
close(output);
halt;
end;
end;
writeln('No'); {无法逃出,输出结果}
writeln(ts[t]);
close(input);
close(output);
end.
第2个回答  2009-11-11
vj上有很多题解吧
第3个回答  2009-11-11
不懂,有题目吗?