主题:这题用动归怎么做……要转移方程
Mato完整版
[专家分:1270] 发布于 2008-07-21 20:15:00
驾车旅行(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个回复)
沙发
Mato完整版 [专家分:1270] 发布于 2008-07-21 20:17:00
这个题用动归怎么做?
这里除了加油站的数目之外,所有的数据都是实数,这个转移方程………………………………怎么写????????????????????????????????????
板凳
angwuy [专家分:2280] 发布于 2008-07-22 09:12:00
试一下用贪心
3 楼
pascal玩家 [专家分:280] 发布于 2008-07-22 16:07:00
呵呵,巧了,这题就在我的一本教材上,信手拈来
例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 楼
小田甜 [专家分:3910] 发布于 2008-07-22 20:00:00
动规转移方程就是那个贪心的……一样!
5 楼
Mato完整版 [专家分:1270] 发布于 2008-07-22 20:49:00
给3楼:
关键此题的第(4)个条件是最烦人的,有可能因为油太多了,驾驶员不想在某个加油站停下来加油。这一点不知道你可考虑到了。
我来回复