题目地址:http://codevs.cn/problem/1046/
分析:
1.如果在能到达的加油站中,油费有比当前加油站便宜的,就到一个距离最近且油费比当前加油站便宜的加油站去,在当前加油站加上刚好能到那个加油站的油,使到达加油站时油用光。
2.如果在能到达的加油站中,油费没有比当前加油站便宜的,那就在此加油站加满油,然后开到能到达的加油站中油费最小的加油站去。
一直循环下去,当能到达终点了,并且后面的站中油费没有更小的了,这就是最终答案。
当找不到加油站了,即无解。
代码:
var d1,c,d2,tot:real; n,i,j,fx:longint; last:real; x:array[0..105] of real;
way,value:array[-1..105] of real; //way:加油站的路程,value:价格,x:加的油量
begin
readln(d1,c,d2,value[0],n);
way[0]:=0;
way[n+1]:=d1;
value[n+1]:=0;
for i:=1 to n do readln(way[i],value[i]);
for i:=0 to n do
begin
last:=last-(way[i]-way[i-1])/d2; //剩余油量
j:=i+1;
fx:=0; //标记这个加油站的类型 0:是接下来最便宜的 1:不是接下来最便宜的 1000:哪怕加满也到不了下一个加油站
while way[j]-way[i]<=c*d2 do
begin
if value[j]<value[i] then
begin
x[i]:=(way[j]-way[i])/d2-last;
if x[i]<0 then x[i]:=0;
last:=last+x[i];
fx:=1;
inc(j);
break;
end;
inc(j);
end;
if j=i+1 then
begin
writeln('No Solution');
fx:=1000;
break;
end;
if fx=0 then
begin
x[i]:=c-last;
last:=c;
end;
end;
for i:=0 to n do
begin
tot:=tot+value[i]*x[i];
end;
if fx<>1000 then
writeln(tot:0:2);
end.