题目描述
一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(0<=N<=100),油站i离出发点的距离Di、每升汽油价格Pi(i=1,2,……N)。计算结果四舍五入至小数点后两位。
如果无法到达目的地,则输出“No solution”。
输入格式
第1行:5个空格分开的数据,分别表示D1 C D2 P N 第2…N+1行:每行3个空格分开的数据,分别表示油站号i, 该油站距出发点的距离Di,该油站每升汽油的价格Pi
输出格式
第1行:一个数据,表示最少费用。
样例输入
275.6 11.9 27.4 2.8 2
1 102.0 2.9
2 220.0 2.2
样例输出
26.95
算法分析
这一题是一道很典型的贪心题,但是很难寻找到最佳贪心策略。
这里的关键是加油站,因为加油站关系到钱的多少。抓住加油站,再思考如何加油最少。
而要总的消费小,那我们每次加油都需要考虑油价尽可能便宜的加油站加油,那么需要在当前的位置下,假如加满油,看看能经过多少个加油站,然后进行判断,那么可以分成三种情况来做
1、首先考虑如果**加满油都不能到达下一个加油站**,则肯定无法到达目的地,
则输出"No Solution"
2、在当前加满油后能到达的所有加油站中比较油价,假如当前位置的油价最低,那么一定要
加满油,然后开到下一个加油站在再次进行比较选择
3、在当前加满油后能到达的所有加油站中比较油价,假如出现了更便宜的加油站,那么只需要
加的油够刚好到达那一个加油站即可
代码
#include<algorithm>
#include<cstdio>
using namespace std;
const int M=100000005;
struct station{
double di,pi;
}a[M];
double kio,ans,oil;
bool flag;
int main(){
double d1,c,d2,p;
int n;
scanf("%lf%lf%lf%lf%d",&d1,&c,&d2,&p,&n);
a[0].di=0,a[0].pi=p,a[n+1].di=d1;
a[n+1].pi=0,kio=c*d2;
for(int i=1;i<=n;i++){
int num;
scanf("%d %lf %lf",&num,&a[i].di,&a[i].pi);
if(a[i].di-a[i-1].di>kio)
flag=true;
}
if(flag==true){
printf("No Solution!");;
return 0;
}
int i=0,j;
while(i<=n){
i=j;
for(j=i+1;j<=n+1;j++){
if(a[j].di-a[i].di>kio){
j--;
break;
}
if(a[j].pi<=a[i].pi){
break;
}
}
if(a[j].pi<=a[i].pi) {
ans+=((a[j].di-a[i].di)/d2-oil)*a[i].pi;
oil=0;
}
else{
ans+=(c-oil)*a[i].pi;
oil=c-(a[j].di-a[i].di)/d2;
}
}
printf("%.2lf",ans);
return 0;
}