这题有点像经典的贪心问题:区间覆盖。
考虑目前所在的点cur要被哪个加油站所承包,自然是找最便宜的加油站承包当前点,然后让当前点向后移动。具体移动到的位置是三者取min(终点,所选加油站能承包到的最远点,离当前点cur最近的下一个加油站的位置)。
#include <bits/stdc++.h>
using namespace std;
int maxc,E,dist,n;
typedef pair<double,int> PDI;
PDI gas[510];
int v[510];
int main()
{
cin>>maxc>>E>>dist>>n;
for(int i=0;i<n;i++)
{
cin>>gas[i].first>>gas[i].second;
gas[i].first=gas[i].first/(double)dist;
v[i]=gas[i].second;
}
sort(v,v+n);
sort(gas,gas+n);
int cur=0;
int maxd=dist*maxc;
double ans=0;
while(cur<E)
{
double minp=1e18;
int u=-1;
for(int i=0;i<n;i++)
if(gas[i].second<=cur&&gas[i].second+maxd>cur)
{
minp=gas[i].first;
u=i;
break;
}
if(-1==u) break;
int pos=upper_bound(v,v+n,cur)-v;
int t=1e9;
if(pos<n) t=v[pos];
t=min(gas[u].second+maxd,t);
t=min(E,t);
ans+=minp*(t-cur),cur=t;
}
if(cur<E) printf("The maximum travel distance = %.2lf",(double)cur);
else printf("%.2lf",ans);
return 0;
}