P1016 [NOIP1999 提高组] 旅行家的预算

P1016 [NOIP1999 提高组] 旅行家的预算

代码思路参考题解,我用双端队列实现了他的油箱按油分类的数组,代码更直观一点,已AC

#include <iostream>
#include <deque>
using namespace std;
int n;
struct Gas_In_Tank//gas_in_tank
{
	double price;
	double sum;
	Gas_In_Tank(double pr,double su)
	{
		price = pr;
		sum = su;
	}
};

double dist , cap , per_dis , min_cost;//距离,容量,每一升油的距离,最小开支
double gas_dist[8] , gas_price[8];//注意范围,本题要求最多6个加油站,0为起点,n+1为终点,故至少数组长度为6+2



int main()
{
	min_cost = 0;

	scanf("%lf%lf%lf%lf%d", &dist , &cap , &per_dis , &gas_price[0] , &n);
	for(int i=1 ; i <= n ; i++) 
	{
		scanf("%lf%lf",&gas_dist[i] , &gas_price[i]);
	}

    
	deque<Gas_In_Tank> gas_in_tank;//内部油按价格排队,front为最低价
	//终点假设一个加油站
	gas_dist[0] = 0;//其实全局变量不需要手动赋0
	gas_dist[n+1] = dist;
	gas_price[n+1] = 0;
	
	gas_in_tank.push_front(Gas_In_Tank(gas_price[0],cap));//出发前加满本地油

	for (int i = 1; i <= n+1; i++)//出发到达每一个站点时
	{
		double gas_cost = (gas_dist[i] - gas_dist[i-1])/per_dis;//耗油
		double gas_add = gas_cost;//耗多少油,就加多少油
		while(!gas_in_tank.empty())//油箱没空,用油箱的油 尝试抵消 耗油量,这个步骤是计算花费的主要步骤s
		{
			if(gas_cost >= gas_in_tank.front().sum)
			{
				min_cost += gas_in_tank.front().sum*gas_in_tank.front().price;//计算耗油钱
				gas_cost -= gas_in_tank.front().sum;
				gas_in_tank.pop_front();
			}
			else
			{
				gas_in_tank.front().sum -= gas_cost;
				min_cost += gas_cost * gas_in_tank.front().price;
				gas_cost = 0;//把耗油算完
				break;
			}
		}

		if(gas_cost > 0)
		{
			printf("No Solution\n");
			return 0;
		}
				
		while(gas_price[i] < gas_in_tank.back().price)//如果现在油比之前贵的油便宜(可能比所有都便宜),那之前的油都白加了,退掉
		{
			gas_add += gas_in_tank.back().sum;//需要加的油会更多,算上退的油
			gas_in_tank.pop_back();
		}//这个退油的过程到终点也会退,但是因为设置终点油价为0,所以会退光,此处可以检验如果i==n+1就不用退了,不影响min_cost计算结果

		gas_in_tank.push_back(Gas_In_Tank(gas_price[i],gas_add));//加满
	}
	
	printf("%.2lf", min_cost);//搜了以下,这里会自动四舍五入,所以不用+0.005
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值