题目描述
一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(N可以为零),油站i离出发点的距离Di、每升汽油价格Pi(i=1,2,…,N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。
输入
第一行有四个数,分别表示D1,C,D2,P,N
接下来有N行,每行2个数,分别表示油站i离出发点的距离Di和每升汽油价格Pi
接下来有N行,每行2个数,分别表示油站i离出发点的距离Di和每升汽油价格Pi
输出
最小费用
样例输入
275.6 11.9 27.4 2.8 2
102.0 2.9
220.0 2.2
样例输出
26.95
#include <bits/stdc++.h> using namespace std; #define precision 0.00001 struct node { double dd,pp; }s[100000]; bool cmp(node a,node b){return a.dd<b.dd;} double d1,c,d2,p; int n; int main(){ //ios::sync_with_stdio(false); int i,j,k; double f,ans,x,y; cin>>d1>>c>>d2>>p>>n; s[1].dd=0,s[1].pp=p; s[2].dd=d1,s[2].pp=0; for(n+=2,i=3;i<=n;i++) cin>>s[i].dd>>s[i].pp; sort(s+1,s+n+1,cmp); k=1,ans=x=0,f=c*d2; while(k<=n) { if(s[k+1].dd-s[k].dd>f) {cout<<"No Solution"<<endl;return 0;}//当路程大于加满油后的最大路程; for(j=k+1;s[j].dd-s[k].dd<=f&&j<=n;j++){//在该油站找遍历可以直接到达的下一个油站 if(s[j].pp<=s[k].pp){//找到比该油站便宜的油 y=(s[j].dd-s[k].dd)/d2;//到达那个油站需要在该油站充多少 if(x<y) ans+=s[k].pp*(y-x),x=0;//到达那个便宜油站后剩余量x=0 else x-=y; k=j;//跳过中间油站 break; } } if(fabs(s[k].dd-d1)<=precision){//到达目的地 printf("%.2lf\n",ans); return 0; } if(j!=k){//找不到合适的 说明本油站是最佳 就在本油站加满油 ans+=s[k].pp*(c-x); x=c-(s[k+1].dd-s[k].dd)/d2;//到下一个油站需要的油 k++; } } return 0; }
要么找不到合适的在本油站加满,要么找到油花费少的,花费至少到达那个油站的油。