PAT 1033. To Fill or Not to Fill (贪心)

3 篇文章 0 订阅

PAT-A的最后一题,终于做出来了... 

是贪心,通过局部最优获得全局最优。


1. 将加油站按距离升序排序

2. 记录当前所在的加油站index,存有的汽油,花费。向后遍历所有 该站可抵达的加油站

3. 遍历中有两种情况:

1) 若发现油价比index更低的站next:

马上跳到该站(此时可能需要加油),不再继续遍历 —— 因为即使想要到达next后面的站,可以通过在next站购买更便宜的汽油来实现

2) 没有发现油价比index更低的站,则选择所有站中油价最低的站作为next:  

此时考虑是否能通过index抵达终点,若能,直接break, 不用管next;  若不能,则装满油,并行驶到next站. 

4. 测试点2测试最大距离为0的情况 —— 即在起始点没有加油站。


代码:

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>

using namespace std;

struct Station
{
	double price;
	int dis;
	Station(double p, int d): price(p), dis(d) {}
	friend bool operator <(const Station& a, const Station& b)
	{
		return a.dis < b.dis;
	}
};

int main()
{
	vector<Station> station;
	double cmax, dest, davg, p;
	int n, d;
	int index = 0; // index indicate the station where they are.
	double cost = 0, gas = 0;
	cin >> cmax >> dest >> davg >> n;
	for (int i = 0; i < n; ++ i)
	{
		cin >> p >> d;
		station.push_back( Station(p, d) );
	}
	sort(station.begin(), station.end());
	if (station[0].dis != 0)
	{
		cout << "The maximum travel distance = 0.00" << endl;
		return 0;
	}

	while ( true )
	{
		// 选择下一个站
		double min_price = 2100000000;
		int next = -1;
		bool find_cheaper = false;
		for (int i = index+1; 
			i<n && station[i].dis<dest && station[i].dis<=station[index].dis+cmax*davg; 
			++ i)
		{
			if (station[i].price <= station[index].price)
			{
				find_cheaper = true;
				next = i;
				break;
			} else if (station[i].price < min_price)
			{
				min_price = station[i].price;
				next = i;
			}
		}
		// 选择加油方式
		if (find_cheaper == true)
		{
			if (station[next].dis - station[index].dis > gas*davg) // 油无法到达该站
			{
				cost += ((station[next].dis-station[index].dis)/davg - gas) * station[index].price;
				gas = 0;
			} else
			{
				gas -= (station[next].dis-station[index].dis)/davg;
			}
			index = next;
		} else if (next != -1) // 至少可以抵达下一个更贵的站
		{
			if (station[index].dis + cmax*davg >= dest)
			{
				break; // 跳出while循环
			}
			cost = cost + (cmax - gas) * station[index].price; // 装满油
			gas = cmax - (station[next].dis - station[index].dis) / davg;
			index = next;
		} else
		{
			break;
		}
	}

	if (station[index].dis + cmax*davg >= dest)
	{
		cost = cost + ((dest-station[index].dis)/davg-gas)*station[index].price;
		cout << setiosflags(ios::fixed) << setprecision(2) << cost;	
	} else
	{
		cout << "The maximum travel distance = " << setiosflags(ios::fixed) << setprecision(2) << station[index].dis + cmax*davg;
	}

	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值