ALGO-15 算法训练 旅行家的预算 (贪心)

问题描述

一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离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

思路:设当前油价的出发时的油价flag(当前使用的油价),每走一站就与当前油站的油价比较,当遇到更便宜的更换油价(贪心思想),否则就结算走到该站所用的油费;直至到达终点

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

double travelExpenses(double length,double v,double len_v,int n,double *p,double *len) {
	double temp = v * len_v;//车能开的距离
	double sum = (len[1]/len_v)*p[0];//总费用
	double sumLen = len[1];
	double flag = p[0];//设为当前使用的油价
	for (int i = 1; i <= n; i++) {	//No Solution的情况:若其中存在两个加油站之间的距离大于车能开的距离temp,则为No Solution
		if (i == 1&&len[i]>temp) {
			return -1;
		}
		else {
			if (p[i] - p[i - 1] > temp)
				return -1;
		}
	}
	int i = 1, k = 2;
	while (i <= n) {
		if (p[i] >= flag) {
			sumLen += len[k] - len[k - 1];
			if (sumLen > temp) {//加满的“便宜”油已经使用完,且无法到达下一站,无奈地采用该站较贵的油
				sum += ((temp - (sumLen - (len[k] - len[k - 1]))) / len_v)*flag;//结算之前剩余的“便宜”油
				flag = p[i];//无奈地采用该站较贵的油,且设为当前使用的油价
				sumLen = sumLen - temp;
				sum += (sumLen / len_v)* flag;//结算从该站能到达下一站的油费
			}
			else {
				sum += ((len[k] - len[k - 1]) / len_v)*flag;
			}
			i++; k++;
		}
		else {
			flag = p[i];
			sumLen = 0;
		}
	}
	return sum;
}

int main() {
	int n;
	double length, v, len_v, price[100];
	double len[100];
	cin >> length >> v >> len_v >> price[0]>>n; //price[0]出发站的油价
	for (int i = 1; i <= n; i++)
		cin >> len[i] >> price[i];
	len[n + 1] = length;//设置终点站

	double sum = travelExpenses(length, v, len_v, n, price, len);
	if (sum < 0)
		cout << "No Solution" << endl;
	else
		printf("%.2lf\n",sum);

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值