1033 To Fill or Not to Fill (25 point(s))

本文介绍了一种基于贪心算法的最优加油策略,通过在每个加油站判断是否继续加油或寻找更便宜的油站,实现从起点到终点的最低油耗成本。文章详细解释了算法流程,并提供了完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题解

贪心题。每到一个油站,加满油能到达的距离是maxdis, 在此路段之间是否有跟便宜的油站。如果有则在原站点只需加油加到能到达此站点。否则原站点加满,有便宜谁不会占啊,你说对不对。

 

#include<iostream>
#include<vector>
#include<cstdio>
#include<algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
struct node {
	double price, dis;
	bool operator < (const node& rhs) const {
		return dis < rhs.dis;
	}
};
vector<node> station;
double cmax, d, davg; //油箱容量, 杭州跟终点的距离, 一个单位油跑的路
int n; // 油站 
int main() {
	scanf("%lf%lf%lf%d", &cmax, &d, &davg, &n);
	station.resize(n + 1);
	for(int i = 0; i < n; ++i) scanf("%lf%lf", &station[i].price, &station[i].dis);
	station[n].price = 0.0, station[n].dis = d; // 边界条件 
	sort(station.begin(), station.end());
	double nowdis = 0.0, leftdis = 0.0, maxdis = 0.0, totalprice = 0.0, nowprice = 0.0;
	if(station[0].dis) {
		printf("The maximum travel distance = 0.00");
		return 0;
	} else nowprice = station[0].price;
	while(nowdis < d) {
		maxdis = nowdis + cmax * davg;
		double minpricedis, minprice = INF;
		bool cheap = false; //找到一个低价油点与否 
		for(int i = 1; i <= n && station[i].dis <= maxdis; ++i) {
			if(station[i].dis <= nowdis) continue; //这个站已经过了
			if(station[i].price < nowprice) {
				totalprice += (station[i].dis - nowdis - leftdis) / davg * nowprice;
				nowprice = station[i].price;
				nowdis = station[i].dis;
				leftdis = 0.0;
				cheap = true; //找到一个更便宜的油站. 
				break;
			} else if(station[i].price < minprice){
				minprice = station[i].price;
				minpricedis = station[i].dis;
			}
		} 
		if(!cheap && minprice != INF) {
			totalprice += nowprice * (cmax - leftdis / davg);
			leftdis = cmax * davg - (minpricedis - nowdis); // 这个油站比较贵,所以在原先油站加满油。
			nowdis = minpricedis;
			nowprice = minprice; 
		} else if(!cheap && minprice == INF) {
			nowdis += cmax * davg;
			printf("The maximum travel distance = %.2f", nowdis);
			return 0; 
		}
	} 
	printf("%.2f", totalprice);
	return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值