[NOIP1999 提高组] 旅行家的预算
题目描述
一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离
D
1
D_1
D1、汽车油箱的容量
C
C
C(以升为单位)、每升汽油能行驶的距离
D
2
D_2
D2、出发点每升汽油价格
P
P
P和沿途油站数
N
N
N(
N
N
N 可以为零),油站
i
i
i 离出发点的距离
D
i
D_i
Di、每升汽油价格
P
i
P_i
Pi(
i
=
1
,
2
,
…
,
N
i=1,2,…,N
i=1,2,…,N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出 No Solution
。
输入格式
第一行, D 1 D_1 D1, C C C, D 2 D_2 D2, P P P, N N N。
接下来有 N N N 行。
第 i + 1 i+1 i+1 行,两个数字,油站 i i i 离出发点的距离 D i D_i Di 和每升汽油价格 P i P_i Pi。
输出格式
所需最小费用,计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出 No Solution
。
样例 #1
样例输入 #1
275.6 11.9 27.4 2.8 2
102.0 2.9
220.0 2.2
样例输出 #1
26.95
提示
N ≤ 6 N \le 6 N≤6,其余数字 ≤ 500 \le 500 ≤500。
分析
显然本体是一道贪心题
1.枚举经过每个加油站所需花费
2.在一个加油站需要加的油,是可以支持车到下一个更便宜加油站的油,如果加满也到不了下一个更便宜的加油站那就加满油,到一个能到达的加油站中最便宜的加油站加油。
3.如果加满油也到不了下一个加油站(目的地),直接输出No Solution。
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
double maxn, ans, d2, t, d1, c, p; //t代表到达一个加油站时油箱里的油还能走多远
int n;
struct node {
double pp;
double d;
}a[30];
int work(int x) {
int cc = -1;
for(int i = x + 1; i <= n && a[i].d - a[x].d <= maxn; i++) {
if (a[i].pp < a[x].pp) { //找到了更便宜的加油站
ans += ((a[i].d - a[x].d - t) / d2) * a[x].pp; // 计算花费
t = 0;
return i;//返回当加油站的编号
}
if (cc == -1 || a[i].pp < a[cc].pp) {
cc = i;
}
}
if (d1 - a[x].d <= maxn) { //可以到达终点
ans += ((d1 - a[x].d - t) / d2) * a[x].pp;
return 1e9;
}
if(cc == -1) { //无法到达任意点
return -1;
} else {
ans += c * a[x].pp; //把油箱加满
t += (maxn - a[cc].d + a[x].d); //到达cc个加油站时油箱里的油还能走过远
return cc;
}
}
int main()
{
cin >> d1 >> c >> d2 >> p >> n;
a[0].d = 0; //把出发点赋值
a[0].pp = p;
for (int i = 1; i <= n; i++) {
cin >> a[i].d >> a[i].pp;
}
maxn = c * d2; //最大能行驶的距离
int t = 0;
while(t != 1e9) { //t=1e9说明到终点了
t = work(t);
if(t == -1) {
cout << "No Solution" << endl;
return 0;
}
}
printf("%.2f", ans);
return 0;
}