【1033 25 贪心】 To Fill or Not to Fill

传送门

题意

给定 \(c_{max}\) 表示油箱最⼤容量,\(d\) 表示杭州到目的地的距离,\(d_{avg}\) 表示平均每单位的汽油可以让汽车行驶的距离,\(n\) 表示加油站数量,每个站有单位油价 \(p_{i}\) 和从杭州的距离 \(d_{i}\),求汽⻋从杭州到终点的最小花费,如果不能够到达,就输出汽车能够行驶的最大距离

数据范围

\(c_{max}\leq 100\)
\(d\leq 30000\)
\(d_{avg}\leq 20\)
\(n\leq 500\)

题解

  • 维护当前背包的油量和总花费
  • 遍历所有能够向前到达的加油站,没有就输出当前站距离+ 背包允许的最大距离 + 如果能有比当前价格低的直接去,当前站只买刚好能到油量
    • 如果没有比当前低的找相对最低的,因为能够到达的没有比当前加油站价格更低的,所以直接贪心买满背包

Code

#include <bits/stdc++.h>
using namespace std;

int main() {
	double Cmax, D, Davg;
	int n;
	cin >> Cmax >> D >> Davg >> n;
	vector<array<double, 2>> stations(n + 1);
	for (auto& it : stations) {
		cin >> it[1] >> it[0];
	}
	stations[n] = {D, 0};
	sort(stations.begin(), stations.end());
	
	if (stations[0][0] > 1e-6) {
		cout << "The maximum travel distance = 0.00";
		return 0;
	}

	int now = 0;
	double ans = 0, C = 0;
	cout << fixed << setprecision(2);
	while (now < n) {
		int to = -1;
		for (int i = now + 1; i <= n and 
			stations[i][0] - stations[now][0] <= Cmax * Davg; i++) {
			if (stations[i][1] < stations[now][1]) {
				to = i;
				break;
			} else {
				if (to == -1 or stations[to][1] > stations[i][1])
					to = i;
			}
		}
		if (to == -1) {
			cout << "The maximum travel distance = " << stations[now][0] + Cmax * Davg;
			return 0;		
		} 
		if (stations[now][1] > stations[to][1]) {
			double p = (stations[to][0] - stations[now][0]) / Davg;
			if (p > C) {
				ans += (p - C) * stations[now][1];
				C = 0;
			} else {
				C -= p;
			}
		} else {
			ans += (Cmax - C) * stations[now][1];
			C = Cmax - (stations[to][0] - stations[now][0]) / Davg;
		}
		now = to;
	}
	cout << ans;
}
posted @ 2021-02-19 18:38  Hyx'  阅读(65)  评论(0)    收藏  举报