洛谷---P1016---旅行家的预算---贪心

P1016 旅行家的预算

资源限制

时间限制:1.0s 内存限制:256.0MB

问题描述

  一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(N可以为零),油站i离出发点的距离Di、每升汽油价格Pi(i=1,2,……N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

输入格式

  第一行为4个实数D1、C、D2、P与一个非负整数N;
  接下来N行,每行两个实数Di、Pi。

输出格式

  如果可以到达目的地,输出一个实数(四舍五入至小数点后两位),表示最小费用;否则输出“No Solution”(不含引号)。

样例输入
275.6 11.9 27.4 2.8 2
102.0 2.9
220.0 2.2
样例输出
26.95

实现代码

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;

double d1, c, d2, p, di, pi, now = 0, cnt = 0;
int n;
typedef pair<double, double> Station;
Station a[1000 + 10];

bool cmp(Station a, Station b) {
	return a.first < b.first;
}

double count(int pos1, int pos2) { // 算两个站之间的费用
	return (a[pos2].first - a[pos1].first) * (a[pos1].second / d2);
}

int main() {
	cin >> d1 >> c >> d2 >> p >> n, a[0] = Station(0, p), a[n + 1] = Station(d1, 0); //把起点和终点加入
	for (int i = 1; i <= n; i++) cin >> di >> pi, a[i] = Station(di, pi);
	sort(a, a + n + 1, cmp);
	int pos = 0;
	double maxd = d2 * c, nowmd = maxd, ans = 0; // 算出可以通过的最大距离maxd, nowmd是当前可以走的最大距离
	while (pos != n + 1) { //循环到该点为终点为止
		// 因为对距离排了序,所以如果下一个点都去不了那么就无解
		if (a[pos + 1].first - a[pos].first > nowmd) cout << "No Solution" << endl, exit(0);
		int minpos = pos + 1; // 用于记录下一个点的标记
		for (int i = pos; i <= n && a[i].first - a[pos].first <= nowmd; i++)
			if (a[i].second < a[pos].second) pos = i; // 从当前点往后找比它花费更少的点,且是可以到达的点
		if (pos != minpos - 1) {
			ans += count(minpos - 1, pos); // 若pos被修改,那么直接计算到那点
			if(nowmd != maxd) nowmd = maxd; 	// 能够成功走达则修改nowmd为最优状态
		}
		else { // 若pos没变,则表明此点为当前最优点

			 // 如果可以用最优点到达终点,那么为最优解
			if (a[n + 1].first - a[pos].first <= nowmd) ans += count(pos, n + 1), pos = n + 1;

			// 如果不能到终点,往后找损耗最小的点
			else {
				for (int i = minpos + 1; a[i].first - a[pos].first <= nowmd; i++)
					if (a[i].second < a[minpos].second) minpos = i;
				// 因为此点是最优点,所以到下一个站为止的油还有剩下的话,那么就将车站的距离变到用完油的后面
				// 且因为后面那段距离是用原来的油走的,所以nowmd要减少
				// nowmd -= nowmd - (a[minpos].first - a[pos].first)转变为下式;
				nowmd = a[minpos].first - a[pos].first; a[minpos].first = maxd + a[pos].first; 
				ans += count(pos, minpos), pos = minpos;
			}
		}
	}
	printf("%.2lf\n", ans);
	return 0;
}
发布了145 篇原创文章 · 获赞 22 · 访问量 9630

猜你喜欢

转载自blog.csdn.net/weixin_44778155/article/details/104592671