Bridge——UVA10037

题目

n people wish to cross a bridge at night. A group of at most two people may cross at any time, and each group must have a flashlight. Only one flashlight is available among the n people, so some sort of shuttle arrangement must be arranged in order to return the flashlight so that more people may cross. Each person has a different crossing speed; the speed of a group is determined by the speed of the slower member. Your job is to determine a strategy that gets all n people across the bridge in the minimum time. Input The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs. The first line of input contains n, followed by n lines giving the crossing times for each of the people. There are not more than 1000 people and nobody takes more than 100 seconds to cross the bridge. Output For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line. The first line of output must contain the total number of seconds required for all n people to cross the bridge. The following lines give a strategy for achieving this time. Each line contains either one or two integers, indicating which person or people form the next group to cross. (Each person is indicated by the crossing time specified in the input. Although many people may have the same crossing time the ambiguity is of no consequence.) Note that the crossings alternate directions, as it is necessary to return the flashlight so that more may cross. If more than one strategy yields the minimal time, any one will do. Sample Input 1 4 1 2 5 10 Sample Output 17 1 2 1 5 10 2 1 2 

 

题目大意

 首先输入一个t 表示测试样例数

注意!!!! 第一次时直接输入n 接下来要先输出空行然后再输入n

  因为这一点我WA10几次都找不出来错误

然后输入n

接下来是n个数据,表示n个人的过桥时间

要求输出最短的过桥时间和过桥策略

(可以一个人单独过桥,也可以两个人同时过桥,但两个人同时过桥时,过桥时间取决于时间较长的那一个)

(过桥的时候必须有手电筒照明,而手电筒只有一个,这就意味着,必须每次都有人回来送手电筒)

 

按过桥时间从小到大排序,存储在数组a[1]到a[n]中

想一想可能有两种方案来过桥

一种是 (让最快与次快的两个人负责运手电筒,这样主要节省掉a[n-1]次慢的过桥时间)

a[1]和a[2]先过桥  ,然后让a[1]送回手电筒

a[n] 和a[n-1](也就是未过桥中最慢与次慢的两个人)过桥,这样会节省掉a[n-1]次慢的过桥时间

然后再让a[2]送回手电筒

这个时候n-=2 因为未过桥人数变成了n-2

再让a[1],a[2]一起过桥

a[1]再回来 

此时的a[n] 和a[n-1](也就是未过桥中最慢与次慢的两个人)过桥 

如此循环

至于是怎么想到这个方法

首先注意到了题目给出的样例就是这样的方法

其次这样会节省掉次慢的时间,大大节约了时间啊

另一种是 (只让a[1](最快的)来运送手电筒,最大节省送手电筒花费的时间)

先让a[1]和a[n]过桥

a[1]回来

a[1]和a[n-1]过桥

a[1]回来

这样也已经过桥两个人了

n-=2

如此循环

这种方法是考虑到节省送手电筒的时间,每次都让最快的人送手电筒,每次话费在手电筒上的时间都做到了最少,所以考虑到这一点

那么每次就判断哪一种方法花费时间更少,选取花费时间少的

 

算法:贪心 

#include<iostream>
#include<algorithm>
using namespace std;
int a[1005]; 
int main()
{
	int t,n;
	cin>>t;
	for(int i=1;i<=t;i++) 
	{
		if(i!=1) cout<<endl;
		cin>>n;
		for(int i=1;i<=n;i++) cin>>a[i];
		sort(a+1,a+n+1);
		int ans=0;
		int tempn=n;
		while(n>=4)
		{
			ans+=min( (a[2]+a[1]+a[n]+a[2]) , (a[n]+a[1]+a[n-1]+a[1]) );
			n-=2;
		} 
		if(n==3) ans+=a[1]+a[3]+a[2];
		if(n==2) ans+=a[2];
		if(n==1) ans+=a[1];
		cout<<ans<<endl;
		
		n=tempn;
		while(n>=4)
		{
			if( (a[2]+a[1]+a[n]+a[2]) < (a[n]+a[1]+a[n-1]+a[1]) )
			{
				cout<<a[1]<<" "<<a[2]<<endl<<a[1]<<endl<<a[n-1]<<" "<<a[n]<<endl<<a[2]<<endl;
			}
			else
			{
				cout<<a[1]<<" "<<a[n-1]<<endl<<a[1]<<endl<<a[1]<<" "<<a[n]<<endl<<a[1]<<endl;
			}
			n-=2;
		} 
		if(n==3) cout<<a[1]<<" "<<a[3]<<endl<<a[1]<<endl<<a[1]<<" "<<a[2]<<endl;
		if(n==2) cout<<a[1]<<" "<<a[2]<<endl;
		if(n==1) cout<<a[1]<<endl;
		
	}
	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cherish_lii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值