UVa Problem 10037 Bridge (过桥)

// Bridge (过桥)
// PC/UVa IDs: 110403/10037, Popularity: B, Success rate: low Level: 3
// Verdict: Accepted
// Submission Date: 2011-05-22
// UVa Run Time: 0.012s
//
// 版权所有(C)2011,邱秋。metaphysis # yeah dot net
//
// 首先将所有过桥时间排序,以下为获得最小过桥时间的算法:
// (1)过桥总人数为 1,该人的过桥时间即为最短过桥时间。
// (2)过桥总人数为 2,过桥时间较大的人的过桥时间即为最短过桥时间。
// (3)过桥总人数为 3,假设为A,B,C,则(AB),(A),(AC)策略和 (AC),(A),(AB)策略
// 的时间相同,3人过桥时间之和为最短时间。
// (4)过桥总人数大于3,假设最前面为A,B两人,最后为Y,Z两人,有两种策略:(AB),(A),(YZ),
// (B),(AB)和(AZ),(A),(AY),(A),(AB)。比较两种策略那种过桥时间少就选那种,然后
// 将总人数减去 2,若总人数仍大于 3,继续该步骤直到剩下需要过桥的人数小于等于 3。可用递归或直接迭代实现。
	
#include <iostream>
#include <algorithm>
	
using namespace std;
	
#define MAXSIZE (1000 + 1)
	
int shortest_time(int time[], int capacity)
{
	if (capacity == 1)
		return time[0];
	
	if (capacity == 2)
		return time[1];
	
	if (capacity == 3)
		return time[0] + time[1] + time[2];
	
	if (2 * time[1] < (time[0] + time[capacity - 2]))
		return time[0] + 2 * time[1] + time[capacity - 1] + 
			shortest_time(time, capacity - 2);
	else
		return 2 * time[0] + time[capacity - 2] + time[capacity - 1] + 
			shortest_time(time, capacity - 2);
}
	
void bridge(int time[], int capacity)
{
	if (capacity == 1)
	{
		cout << time[0] << "\n";
		return;
	}
	
	if (capacity == 2)
	{
		cout << time[0] << " " << time[1] << "\n";
		return;
	}
	
	if (capacity == 3)
	{
		cout << time[0] << " " << time[2] << "\n";
		cout << time[0] << "\n";
		cout << time[0] << " " << time[1] << "\n";
		return;
	}
	
	if (2 * time[1] < (time[0] + time[capacity - 2]))
	{
		cout << time[0] << " " << time[1] << "\n";
		cout << time[0] << "\n";
		cout << time[capacity - 2] << " " << time[capacity - 1] << "\n";
		cout << time[1] << "\n";
	}
	else
	{
		cout << time[0] << " " << time[capacity - 1] << "\n";
		cout << time[0] << "\n";
		cout << time[0] << " " << time[capacity - 2] << "\n";
		cout << time[0] << "\n";
	}
	
	bridge(time, capacity - 2);
}
	
int main(int ac, char *av[])
{
	int cases;
	int time[MAXSIZE];
	int capacity, index;
	
	cin >> cases;
	while (cases--)
	{
		// 总人数。
		cin >> capacity;

		// 读取每个人的过桥时间。
		index = 0;
		while (index < capacity)
			cin >> time[index++];
	
		// 将用时数组予以排序。
		sort(time, time + capacity);

		// 计算最短过桥时间,输出过桥顺序。
		cout << shortest_time(time, capacity) << endl;
		bridge(time, capacity);

		if (cases)
			cout << endl;
	}
	
	return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值