问题描述
一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离 D 1 D1 D1、汽车油箱的容量 C C C(以升为单位)、每升汽油能行驶的距离 D 2 D2 D2、出发点每升汽油价格 P P P和沿途油站数 N N N( N N N可以为零),油站i离出发点的距离 D i Di Di、每升汽油价格 P i Pi Pi( i = 1 , 2 , … … N i=1,2,……N i=1,2,……N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“ N o No No S o l u t i o n Solution Solution”。
输入格式
第一行为4个实数 D 1 、 C 、 D 2 、 P D1、C、D2、P D1、C、D2、P与一个非负整数 N N N;
接下来 N N N行,每行两个实数 D i 、 P i Di、Pi Di、Pi。
输出格式
如果可以到达目的地,输出一个实数(四舍五入至小数点后两位),表示最小费用;否则输出“ N o No No S o l u t i o n Solution Solution”(不含引号)。
样例输入
275.6 11.9 27.4 2.8 2
102.0 2.9
220.0 2.2
样例输出
26.95
个人思路:【贪心】
- 1)首先考虑如果加满油都不能到达下一个加油站,则肯定无法到达目的地,则输出" N o No No S o l u t i o n Solution Solution"
- 2)既然是贪心,那么费用得最少。
- 寻找下一个比当前加油站便宜的加油站,如果能找到比当前加油站便宜的加油站,且一次加油即可到达,则把油加到刚好能到达该加油站即可,否则把油加到最满,行驶到最大距离之前的加油站,然后再加油到该便宜的加油站;如果不能到达,则把油加满,行驶到最大距离之前的加油站
#include <iostream>
#include <cstdio>
using namespace std;
double D1, C, D2, P, N;
double Dis[1005]; //记录加油站的距离
double Price[1005]; //记录加油站的价格
double maxdis, total, remain; //分别表示从起点加满油所能到达的最远距离、总费用、剩余油量
int main() {
int N;
cin >> D1 >> C >> D2 >> P >> N;
Dis[0] = 0; //标记起点为第一个加油站
Price[0] = P;
Dis[N + 1] = D1; //标记终点为最后一个加油站
Price[N + 1] = 0;
maxdis = C * D2; //标记最远达到的距离
bool flag = true;
for (int i = 1; i <= N; ++i) {
cin >> Dis[i] >> Price[i];
//判断下一个加油站是否可达,如不可达则无解
if (Dis[i] - Dis[i - 1] > maxdis)
flag = false;
}
if (!flag) {
cout << "No Solution!" << endl;
return 0;
}
/*
* i:当前加油站的编号
* j:下一个比当前便宜的加油站
*/
for (int i = 0, j; i <= N; i = j) //到达j之后,令j为当前加油站,重新循环
{
for (j = i + 1; j <= N + 1; j++)//从当前加油站i的下一个开始寻找比i便宜的加油站
{
if (Dis[j] - Dis[i] > maxdis) //如果不能行驶到比它便宜的加油站
{
j--; //则先行驶到加满油能行驶到的最大距离之前的加油站,即i->j之间的加油站
break;
}
if (Price[j] <= Price[i]) { //找比当前加油站便宜的加油站
break;
}
}
/*
* 从当前位置的下一个加油站寻找距离近且便宜的加油站
* 1. 如果能找到
* (1) 如果能一次加油到达便宜的加油站,那么把油加到刚好能到达这个便宜的加油站即可
* (2) 如果不能一次到达,那么把油加满,到达行驶最大距离之前的加油站,再加油到这个便宜的加油站
* 2. 如果不能找到,则加满油,到达行驶最大距离之前的加油站
*
*/
if (Price[j] <= Price[i]) { //找到比当前便宜的加油站
total += ((Dis[j] - Dis[i]) / D2 - remain) * Price[i]; //加到刚好能到达j即可
remain = 0;
}
else { //不能一次到达或不能找到
total += (C - remain) * Price[i]; //把油加满
remain = C - (Dis[j] - Dis[i]) / D2; //剩余油量
}
}
printf("%.2lf\n", total);
return 0;
}