因为汽油的价格各有不同但是走的路程相同,所以我们尽可能选价格少的汽油,实际情况我们需要维护一个类单调队列,尽可能用小的代替大的,分为几种情况
1、如果在这个加油站即使加满油,都不能到达一个比它油价低的加油站,就把油箱加满,前往能够到达的加油站中油价最低的那个;
2、如果只在这个加油站就可以到达一个比他油价低的加油站,就加到正好能到达油价低的加油站为止;
3、如果没有比当前加油站油价低的,重复1;
4、如果在这个加油站即使加满油,都不能到达任意一个加油站,也不能到达终点城市,说明无解;
代码写的略显粗糙:
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 double d1,c,d2,p; 7 int n; 8 double ans=0; 9 struct node{ 10 double x,cos; 11 }station[100]; 12 bool cmp(node x,node y){ 13 return x.x<y.x; 14 } 15 void money(int nowid,double w){ 16 int pos=0; 17 double s; 18 s=station[nowid].x+w*d2; 19 if (s>=d1)return; 20 else if (nowid==n){ 21 if (station[n].x+c*d2>=d1){ 22 ans+=(d1-s)*station[n].cos/d2; 23 return; 24 } 25 ans=0;return; 26 } 27 if (double(station[nowid].x+c*d2)<station[nowid+1].x){ans=0;return;} 28 for (int i = nowid+1;i <= n;i++){ 29 if (station[i].cos<station[nowid].cos) {pos = i;break;} 30 } 31 if (station[nowid].x+c*d2<station[pos].x||pos==0){//如果油价一定上涨 32 ans+=station[nowid].cos*(c-w); 33 if( station[nowid].x+c*d2>d1) ans-=(station[nowid].x+c*d2-d1)/d2*station[nowid].cos; 34 int pos1=0; 35 double cost=500*1.0; 36 for (int i = nowid+1;station[nowid].x+c*d2 >= station[i].x&&i<=n;i++){ 37 if (station[i].cos<cost) pos1=i; 38 } //找到最小的一个 39 money(pos1,c-(station[pos1].x-station[nowid].x)/d2); 40 } 41 else {//如果油价可以下降 42 // cout<<1<<endl; 43 ans+=station[nowid].cos*(station[pos].x-station[nowid].x)/d2; 44 money(pos,0); 45 } 46 } 47 int main(){ 48 scanf ("%lf%lf%lf%lf%d",&d1,&c,&d2,&p,&n); 49 for (int i = 1;i <= n;i++){ 50 scanf ("%lf%lf",&station[i].x,&station[i].cos); 51 } 52 station[0].x=0;station[0].cos=p; 53 sort(station,station+n+1,cmp); 54 money(0,0); 55 if (ans==0) cout<<"No Solution"<<endl; 56 else printf ("%.2f",ans); 57 return 0; 58 } 59 /* 60 87.75 13.03 5.75 7.29 3 61 22.10 7.38 62 24.21 6.81 63 82.08 6.96 64 */