驾车旅游
题目描述
如今许多普通百姓家有了私家车,一些人喜爱自己驾车从一个城市到另一个城市旅游。自己驾车旅游时总会碰到加油和吃饭的问题,在出发之前,驾车人总要想方设法得到从一个城市到另一个城市路线上的加油站的列表,列表中包括了所有加油站的位置及其每升的油价(如 3.25 3.25 3.25 元/L)。驾车者一般都有以下的习惯:
- 除非汽车无法用油箱里的汽油达到下一个加油站或目的地,在油箱里还有不少于最大容量一半的汽油时,驾驶员从不在加油站停下来;
- 在第一个停下的加油站总是将油箱加满;
- 在加油站加油的同时,买快餐等吃的东西花去 20 20 20 元。
- 从起始城市出发时油箱总是满的。
- 加油站付钱总是精确到 0.1 0.1 0.1 元(四舍五入)。
- 驾车者都知道自己的汽车每升汽油能够行驶的里程数。
现在要你帮忙做的就是编写一个程序,计算出驾车从一个城市到另一个城市的旅游在加油和吃饭方面最少的费用。
输入格式
第一行是一个实数,是从出发地到目的地的距离(单位:km)。
第二行是三个实数和一个整数,其中第一个实数是汽车油箱的最大容量(单位:L);第二个实数是汽车每升油能行驶的公里数;第三个实数是汽车在出发地加满油箱时的费用(单位:元);一个整数是 1 1 1 到 50 50 50 间的数,表示从出发地到目的地线路上加油站的数目。
接下来 n n n 行都是两个实数,第一个数表示从出发地到某一个加油站的距离(单位:km);第二个实数表示该加油站汽油的价格(单位:元)。
数据项中的每个数据都是正确的,不需判错。一条线路上的加油站根据其到出发地的距离递增排列并且都不会大于从出发地到目的地的距离。
输出格式
输出一个实数,即精确到 0.1 0.1 0.1 元的最小的加油和吃饭费用。
样例 #1
样例输入 #1
600
40 8.5 128 3
200 3.52
350 3.45
500 365
样例输出 #1
13133.2
#include <bits/stdc++.h>
using namespace std;
double dis, maxn, sl, money, ans;
int n;
double s[51], dj[51];
void dfs(int xh, double x, double y) { //xh 为当前加油站序号, x 为当前油量, y 为已花钱数
if (y > ans)return; //剪枝
if (xh == n + 1) { //到终点了
ans = min(ans, y);
return;
}
if (x * sl >= s[xh + 1] - s[xh]) { //油够到下一个加油站
if (x * 2 >= maxn) { //油不少于一半(不加)
dfs(xh + 1, x - (s[xh + 1] - s[xh]) / sl, y);
} else {
dfs(xh + 1, x - (s[xh + 1] - s[xh]) / sl, y); //不加
dfs(xh + 1, maxn - (s[xh + 1] - s[xh]) / sl, y + 20 + (maxn - x)*d
j[xh]); //加
}
} else { //油不够到下一个加油站
dfs(xh + 1, maxn - (s[xh + 1] - s[xh]) / sl, y + 20 + (maxn - x)*dj[x
h]); //必须加
}
}
int main() {
cin >> dis >> maxn >> sl >> money >> n;
ans = money;
for (int i = 1; i <= n; i++) {
cin >> s[i] >> dj[i];
ans += 20 + maxn * dj[i]; //把 ans 整大点
}
s[n + 1] = dis; //终点也标记上
dfs(1, maxn - s[1] / sl, money);
printf("%.1lf", ans);
return 0;
}