回 帖 发 新 帖 刷新版面

主题:这题用动归怎么做……要转移方程

驾车旅行(tour.pas)
【问题描述】
一个人要驾车从A地到B地,这中间有一些加油站,每个加油站的油价可能不相同。
这个人知道每个加油站到起点(A地)的距离和加油站里的油价(单位:元/升),他有以下习惯:
(1)在A地出发时车的油箱是满的。
(2)在第一个停下来的加油站处总是把油箱加满,在以后的加油站中不一定要把油箱加满。
(3)在加油站加油时,需要花20元吃饭。
(4)到达某个加油站时,除非车里的油不够到达下一个加油站或B地(如果是最后一个加油站的话),在车里的油超过或达到油箱容量的一半时,这个人从不停下来加油,他觉得这样浪费钱。
现在这个人告诉你每个加油站的油价和距离,让你帮他算出从A地到B地在加油站里最少要付多少钱。注意,在加油站付的油钱总是精确到角(即保留一位小数),后面的四舍五入。
【输入文件】
输入文件tour.in的第一行有一个实数,是A地到B地的距离(单位:公里)。
第二行两个实数和一个整数,分别表示油箱的最大容量、每升油能行驶的公里数和A地到B地加油站的数目N(1<=N<=40)。
接下来N行,每行2个实数,分别表示每个加油站到A地的距离和这个加油站的油价。
输入文件保证距离都大于0小于A地到B地的总距离,且递增排列。
【输出文件】
一个只有一位小数的实数,表示从A地到B地在加油站里最少要付的钱。
【样例输入】
600.0
40.0 8.5 3
200.0 3.52
350.0 3.45
500.0 3.65
【样例输出】
251.6

回复列表 (共5个回复)

沙发

这个题用动归怎么做?

这里除了加油站的数目之外,所有的数据都是实数,这个转移方程………………………………怎么写????????????????????????????????????

板凳

试一下用贪心

3 楼

呵呵,巧了,这题就在我的一本教材上,信手拈来
例5:旅行家的预算问题: 

一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市,给定两个城市间的距离d1,汽车油箱的容量是c,每升汽油能行驶的距离d2,出发时每升汽油的价格是p,沿途加油站数为n(可为0),油站i离出发点的距离是di,每升汽油的价格是pi。 

计算结果四舍五入保留小数点后两位,若无法到达目的地输出“No answer" 

 若输入: 

d1=275.6   c=11.9   d2=27.4   p=8   n=2 

d[1]=102     p[1]=2.9 

d[2]=220     p[2]=2.2 

output 

26.95 

本问题的贪心策略是:找下一个较便宜的油站,根据距离确定加满、不加、加到刚好到该站。 

程序如下: 

program jiayou;
const maxn=10001;
zero=1e-16;
type
 jd=record
  value,way,over:real;
 end;
var oil:array[1..maxn] of ^jd;
 n:integer;
 d1,c,d2,cost,maxway:real;
function init:boolean;
var i:integer;
begin
 new(oil[1]);
 oil[1]^.way:=0;
 read(d1,c,d2,oil[1]^.value,n);
 maxway:=d2*c;
 for i:=2 to n+1 do
  begin
   new(oil[i]);
   readln(oil[i]^.way,oil[i]^.value);
   oil[i]^.over:=0;
  end;
 inc(n,2);
 new(oil[n]);
 oil[n]^.way:=d1;
 oil[n]^.value:=0;
 oil[n]^.over:=0;
 for i:=2 to n do
  if oil[i]^.way-oil[i-1]^.way>maxway then
   begin
    init:=false;
    exit
   end;
init:=true;
end;
procedure buy(i:integer;miles:real);
begin
 cost:=cost+miles/d2*oil[i]^.value;
end;
procedure solve;
var i,j:integer;
  s:real;
begin
 i:=1;j:=i+1;
 repeat
  s:=0.0;
  while( s<=maxway+zero) and (j<=n-1) and (oil[i]^.value<=oil[j]^.value) do
   begin
   inc(j);
   s:=s+oil[j]^.way-oil[j-1]^.way
   end;
  if s<=maxway+zero then
   if (oil[i]^.over+zero>=oil[j]^.way-oil[i]^.way) then
    oil[j]^.over:=oil[i]^.over-(oil[j]^.way-oil[i]^.way) else
    begin
     buy(i,oil[j]^.way-oil[i]^.way-oil[i]^.over);
     oil[j]^.over:=0.0;
    end
   else begin
    buy(i,maxway-oil[i]^.over);
    j:=i+1;
    oil[j]^.over:=maxway-(oil[j]^.way-oil[i]^.way);
    end;
   i:=j;
 until i=n;
 end;
begin
 cost:=0;
 if init then begin
  solve;
  writeln(cost:0:2);
  end else writeln('No answer');
end. 

但是这道题不用吃饭,你还得改改

4 楼

动规转移方程就是那个贪心的……一样!

5 楼

给3楼:
     关键此题的第(4)个条件是最烦人的,有可能因为油太多了,驾驶员不想在某个加油站停下来加油。这一点不知道你可考虑到了。

我来回复

您尚未登录,请登录后再回复。点此登录或注册