暴力摩托(NDK1045)

本文探讨在玩‘暴力摩托’游戏时如何选择最优的加油方案,以最少的时间跑完全程。通过分析赛道长度、油耗及加油所需时间,利用动态规划算法找到最短用时策略。
暴力摩托

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.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值