poj 1700 过河问题 贪心法

本文介绍了一种基于贪心策略解决特定过河问题的算法实现。该算法通过比较不同过河组合的时间成本来确定最优方案,适用于人数不等的情况,并详细展示了算法的流程与核心逻辑。
#include <iostream>
#include <algorithm>
using namespace std;

/*
贪婪法:
1)当人数<3时:直接过
2)当人数=3时:假设为a,b,c.(升序)
如果用最小的来送:c+a+b=c+b+a
如果大的一起过:c+b+b=c+2b.
所以这个时候用小的来送.
3)当人数=4时,a,b,c,d(升序)
如果用最小的来送:d+a+c+a+b=d+c+b+2a
如果先让最小的两个过河,再让其中一个回来,
让最大的两个过河,再让前一步过去留下的那个回来,
再让最小的2个过河
也就是说小的两个过去2次,再单独回来一次.
2b+b+a+d=d+3b+a 
当d+c+b+2a<=d+3b+a时,也就是c-2b+a<=0时,第一种方法过.
否则用另外一种办法
4)当人数>4时,a,b,..,c,d(升序)
过去,回来,过去,回来(船要回来),让最大的2个过去.
很笨的时间是d+c+c+a=d+2c+a(所有时间都写出来后会发现时最慢的)
如果让最小的来送:d+a+c+a=d+c+2a
否则:b+b+a+d=d+2b+a
如果d+c+2a<=d+2b+a,也就是c-2b+a<=0时,第一种方法过
*/

int main()
{
	//freopen("in.txt", "r", stdin);
	int p[1005],t,n;
	cin>>t;
	while(t--)
	{
		cin>>n;
		int i = 0;
		while(i < n)
			cin>>p[i++];
		sort(p, p + n);//左闭右开
		int sum = 0;
		while(n)
		{
			if(n == 1)
			{
				sum += p[0];
				n = 0;
			}
			else if(n == 2)
			{
				sum += p[1];
				n = 0;
			}
			else if(n == 3)
			{
				sum += (p[0] + p[1] + p[2]);
				n = 0;
			}
			else if(n == 4)
			{
				if(p[2] - 2 * p[1] + p[0] <= 0)
					sum += (p[3] + p[2] + p[1] + 2 * p[0]);
				else
					sum += (p[3] + 3 * p[1] + p[0]);
				n = 0;
			}
			else
			{
				if(p[n - 2] - 2 * p[1] + p[0] <= 0)
					sum += (p[n - 1] + p[n - 2] + 2 * p[0]);
				else
					sum += (p[n - 1] + 2 * p[1] + p[0]);
				n -= 2;
			}
		}
		cout<<sum<<endl;
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值