贪心思想:在里程内(例子中为50*12=600)找到第一个比现在便宜的站,把油加到刚好能开到他那里即可。如果发现里程内都比现在贵,那就趁着便宜赶紧把油加满,然后开到里程内最便宜的车站去。如果都找不到,结束算法。
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
struct node//加油站
{
double price;
double dis;
}T[505];
bool cmp(node a,node b)
{
return a.dis < b.dis;
}
int main()
{
// freopen("in.txt","r",stdin);
double C,D,A;
double tank=0;
int N;
scanf("%lf %lf %lf %d",&C,&D,&A,&N);
double l=C*A;//l表示满油情况下最多可以跑的路程
double cost=0,tra=0;
for(int i=0;i<N;i++)
{
scanf("%lf %lf",&T[i].price,&T[i].dis);
}
sort(T,T+N,cmp);
if(N==0 || T[0].dis!=0)
{
printf("The maximum travel distance = 0.00");
return 0;
}
T[N].price=0;//把终点也视为一个加油站,价格为0
T[N].dis=D;
N++;
int now=0;//现在所在的加油站
while(now!=N-1)//只要还没到最后一个加油站,就循环
{
int next=-1;//找l以内第一个比现在便宜的
int pmin=-1;//找l以内最便宜的当备用
int p=now+1;
double Min=9999999;
while(p<N && T[p].dis-tra<=l)
{
if(T[p].price < T[now].price)
{
if(next==-1)
next=p;
}
if(T[p].price < Min)
{
Min=T[p].price;
pmin=p;
}
p++;
}
if(next==-1)//没找到比现在小的
{
if(pmin!=-1)//如果有备用,就用备用
next=pmin;
else//方圆600里没有可以到达的车站
break;
}
if(T[next].price < T[now].price)//如果下个站更便宜,那么加到下次车站为止
{
cost+=((T[next].dis-T[now].dis)/A-tank)*T[now].price;//付钱
tank+=(T[next].dis-T[now].dis)/A-tank;//加油
}
else//如果下个车站相同价格或者更贵,加满
{
cost+=(C-tank)*T[now].price;//付钱
tank=C;//加油
}
tra+=T[next].dis-T[now].dis;//加里程
tank-=(T[next].dis-T[now].dis)/A;//减油
now=next;//到达下一站
}
if(now==N-1)//到最后一个加油站了
printf("%.2f",cost);
else//半路出来的
printf("The maximum travel distance = %.2f",tra+l);
return 0;
}