Time Limit:1000MS Memory Limit:65536K
Total Submit:18 Accepted:11
Description
晚会上大家在玩一款“暴力摩托”的游戏,它拥有非常逼真的画面和音箱效果!
当然了,车子总是要加油的咯,已知赛道长S公里(S<=10000整数,且为10的倍数),赛车的油耗Q=1,即1公里路耗油1个单位的油。Q不变,赛车的油箱为无穷大,同时在沿途的任何地方都可以加油。约定,每次加油的数量为整数,且为10的倍数,赛车的数度与赛车加油后的总油量有关。其关系如下表所示:
加油量 车速(公里/小时)
<=10 100
(10,20) 90
(20,30) 80
(30,40) 75
(40,+ ∞) 70
同时,汽车每加油一次需要耗油T分钟(T<=100不论加油多少,开始时的加油不计时间)。
当S,T给出之后,选择一个最优的加油方案,使汽车以最少时间跑完全程。
例如:当S=40,T=6(分钟),加油的方案有许多种,列出一些:
(1) 起点加油40,用时40/75≈0.53小时
(2) 起点加油20,中途加20,用时20/90+20/90+6/60(化为小时)≈0.54小时
Input
一行,为两个整数S,T。
Output
输出一行,为最少用时(保留两位小数)
Sample Input
40 6
Sample Output
0.53
Source
NOIdaokan
算法:DP
用f[i]表示在i点停车的最小费用,那么就从前面找一个最小的f[j],再加上从j到i需要的油的费用更新f[i]即可,类似于LIS。
注意题目中的数都是10的倍数,因此先把数都直接除以10。
program NDK1045;
const
maxn=1000;
var
s,t:longint;
mincost1,mincost:real;
f:array [0..maxn] of real;
procedure main;
var
i,j:longint;
begin
s:=s div 10;
for i:=1 to s do
begin
case i of
1:mincost:=1/10;
2:mincost:=2/9;
3:mincost:=3/8;
4:mincost:=4/7.5;
else mincost:=i/7;
end;{case}
for j:=1 to i-1 do
begin
case i-j of
1:mincost1:=1/10;
2:mincost1:=2/9;
3:mincost1:=3/8;
4:mincost1:=4/7.5;
else mincost1:=(i-j)/7;
end;{case}
mincost1:=mincost1+t/60;
if mincost1+f[j]<mincost then mincost:=mincost1+f[j];
end;
f[i]:=mincost;
end;
end;
begin
assign(input,'NDK1045.in'); reset(input);
assign(output,'NDK1045.out'); rewrite(output);
readln(s,t);
main;
writeln(f[s]:0:2);
close(input); close(output);
end.
本文探讨在玩‘暴力摩托’游戏时如何选择最优的加油方案,以最少的时间跑完全程。通过分析赛道长度、油耗及加油所需时间,利用动态规划算法找到最短用时策略。
5万+

被折叠的 条评论
为什么被折叠?



