To Fill or Not to Fill(贪心)

题目描述

With highways available, driving a car from Hangzhou to any other city is easy. But since the tank capacity of a car is limited, we have to find gas stations on the way from time to time. Different gas station may give different price. You are asked to carefully design the cheapest route to go.

输入描述:

For each case, the first line contains 4 positive numbers: Cmax (<= 100), the maximum capacity of the tank; D (<=30000), the distance between Hangzhou and the destination city; Davg (<=20), the average distance per unit gas that the car can run; and N (<= 500), the total number of gas stations. Then N lines follow, each contains a pair of non-negative numbers: Pi, the unit gas price, and Di (<=D), the distance between this station and Hangzhou, for i=1,...N. All the numbers in a line are separated by a space.

输出描述:

For each test case, print the cheapest price in a line, accurate up to 2 decimal places. It is assumed that the tank is empty at the beginning. If it is impossible to reach the destination, print "The maximum travel distance = X" where X is the maximum possible distance the car can run, accurate up to 2 decimal places.
示例1

输入

50 1300 12 8
6.00 1250
7.00 600
7.00 150
7.10 0
7.20 200
7.50 400
7.30 1000
6.85 300
50 1300 12 2
7.10 0
7.00 600

输出

749.17
The maximum travel distance = 1200.00

分析如下:

使用贪心算法策略,先按距离由近到远排序;然后遍历每个加油站:
(1): 如果不是初始站,到达每一个站时,都要更新油箱容量;
(2):从下一个加油站开始,寻找第一个比当前站油价小的站k;
(3): 假如当前站i,加满油后,仍然到不了k站,说明站i的油价是汽车可达距离内,油价最小的站;
加满油:更新油箱剩余量;
更新总费用;
否则:
计算站i到站k还要加多少油;
更新总费用和油箱剩余量;

(4):判断站i,在加满油的情况下,能到达下一站么


代码如下:

#include<stdio.h>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAX 500

struct Station
{
	double price;
	double dis; //注意把其也定义为double类型
};
Station stats[MAX+1];  //终点站也看做是一个油站,价格初始化为最大
int Cmax, D, Davg, N;   //油箱容量;到终点的距离;每单位油可跑的路程;站的数量;
double leftTank, sumFee, step; //剩余油量;总费用;油箱加满时,能跑的最大距离;

int cmp(Station s1,Station s2)
{
	return s1.dis<s2.dis;
}

void getOneTest()
{
	int i;
	for(i=0;i<N;i++)
		scanf("%lf%lf",&stats[i].price, &stats[i].dis);
	stats[N].dis=D;  //最后一站是终点
	stats[N].price=100;  //价格设置最大
	sort(stats,stats+N+1,cmp);  //按离起点的距离由近到远排序
	
	if(stats[0].dis>0) //车不在最近的油站
	{
		printf("The maximum travel distance = 0.00\n");
		return;
	}
	leftTank=0;
	sumFee=0;
	step=Cmax*Davg;
	for(i=0;i<N;i++)
	{
		if(i>0)
			leftTank=leftTank-(stats[i].dis-stats[i-1].dis)*1.0/Davg; //更新剩余油量
		int k=i+1;
		for(;k<N && stats[k].price>=stats[i].price;k++) //找到离站i最近的,价格比stats[i].price小的站k
			continue;
		if(stats[k].dis-stats[i].dis>step) //站i加满油后,无法到达站k; 说明站i的油价是可达距离内的最小价格
		{
			sumFee=sumFee+(Cmax-leftTank)*stats[i].price; //更新总费用
			leftTank=Cmax; //加满油
		}
		else //站k的油价是可达距离内的最小价格
		{
			double tempNeed=(stats[k].dis-stats[i].dis)*1.0/Davg; //到达站k,一共需要的油
			tempNeed=tempNeed-leftTank;  //还需要再加的油
			if(tempNeed>0 && fabs(tempNeed)>1e-5) //需要的油大于剩余油量
			{
				sumFee=sumFee+tempNeed*stats[i].price;
				leftTank=leftTank+tempNeed; //更新剩余油
			}
		}
		if(stats[i+1].dis-stats[i].dis>step)
		{
			printf("The maximum travel distance = %.2lf\n",stats[i].dis+step);
			break;
		}
	}
	if(i==N)
		printf("%.2lf\n",sumFee);
}

int main()
{
	while(scanf("%d%d%d%d",&Cmax,&D,&Davg,&N)!=EOF)
		getOneTest();
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值