方法:贪心策略:分三种情况:1,该站加满油无法到达下一站,直接输出;2,该站(A站)加满油能到达的范围内,若有比该站油价的站,找到最近的比本站便宜的站(B站),只加至到达B站的量(油箱可能有剩余的油);3,该站加满油能到达的范围内,本站的油最便宜,加满。
注意点:第一个站点的距离可能不为零,此时,直接输出max distance :0.0。
#include <iostream>
#include <algorithm>
using namespace std;
struct station{
int dis;
float price;
};
int cmax,sumd,nums;
float davg,sump=0,currentv=0; //currentv 表示当前油箱的油量
station st[520];
bool cmp(station a,station b){
return a.dis<b.dis;
}
void calvolume(int pos){
float maxdis=st[pos].dis+cmax*1.0*davg; //当前加油站加满油后能到达的最远点
int lasts=pos;
for(int i=pos+1;st[i].dis<=maxdis&&i<=nums;i++)
lasts=i;
for(int i=pos+1;i<=lasts;i++){
if(st[i].price<=st[pos].price){
if(currentv*davg>=st[i].dis-st[pos].dis) return;
//油箱的油足够带到下一站,故可直接返回,该站不加油
sump+=(st[i].dis-st[pos].dis-currentv*davg)*st[pos].price; //只加到刚好到达station[i]的 量
currentv=(st[i].dis-st[pos].dis)*1.0/davg;
return;
}
}
sump+=(cmax-currentv)*davg*st[pos].price; //station[pos]所到范围内,本站的价格最低,所以加满
currentv=cmax;
}
int main(){
scanf("%d%d%f%d",&cmax,&sumd,&davg,&nums);
for(int i=0;i<nums;i++){
scanf("%f%d",&st[i].price,&st[i].dis);
}
sort(st,st+nums,cmp);
if(st[0].dis!=0){
printf("The maximum travel distance = 0.00");
return 0;
}
st[nums].dis=sumd; //
st[nums].price=0; //
for(int i=0;i<nums;i++){
if(st[i].dis+cmax*1.0*davg<st[i+1].dis){
printf("The maximum travel distance = %.2f",st[i].dis+cmax*1.0*davg);
return 0;
}
calvolume(i);
currentv-=(st[i+1].dis-st[i].dis)/davg; //更新油量
}
printf("%.2f",sump*1.0/davg);
return 0;
}