POJ 1700 Crossing River

本文探讨了一群人使用一条最多可载两人的小船过河的问题,旨在寻找一种策略,使所有人在最短时间内完成过河。文章提供了详细的解题思路,包括时间排序和两种过河方案的比较,最终通过代码实现了解决方案。

A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the boat back and forth so that all people may cross. Each person has a different rowing speed; the speed of a couple is determined by the speed of the slower one. Your job is to determine a strategy that minimizes the time for these people to get across.

Input

The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. The first line of each case contains N, and the second line contains N integers giving the time for each people to cross the river. Each case is preceded by a blank line. There won’t be more than 1000 people and nobody takes more than 100 seconds to cross.

Output

For each test case, print a line containing the total number of seconds required for all the N people to cross the river.

Sample Input

1
4
1 2 5 10

Sample Output

17

题意描述:

给出你个数n,下边便有n个数,然后这n个数表示这n个人的划船过河时间,现在只有一条小船,每次能过两个人,划船时间按最初长的那个算,问这n个人全部过河需要多长时间。

解题思路:

时间从小到大排序,要想时间最短,返航时间要最短,因此出现两中方法

第一种最快的速度两次返航(最快和最慢的过河,返航后和次慢的过河在返航)2*s[0]+s[j]+s[j-1];

第二种最快的和次快的过河,最快返航,之后最慢和次慢的过河,然后次快返航。s[j]+s[0]+2*s[1];

因此只需要从这两中找出最短的累加就可以了。

需要特别注意在j==2是人已经全部到达对岸因此此时需要跳出循环。

AC代码

#include<stdio.h>
#include<algorithm>
using namespace std;

 int main(void)
 {
 	int i,j,t,n,a,b,c,d,s[1010];
 	long long sum;
 	scanf("%d",&t);
 	while(t--){
 		sum=0;
 		scanf("%d",&n);
 		for(i=0;i<n;i++)
 			scanf("%d",&s[i]);
 		sort(s,s+n);
 	
		a=s[0];b=s[1];
 		c=s[2];d=s[3];
	 	for(j=n-1;j>=0;j=j-2){
			if(j==0)
				sum=sum+a; 
			else if(j==1)
				sum=sum+b;
			else if(j==2) {//解释:无论那种情况最后一定是最快和次快的在河对岸。 
				sum=sum+a+b+c;//因为要不最快是返航,要不就是最快和次快都是返航的。
				break;//避免重复加 
			}	
		 	else{
		 		sum=sum+min(2*a+s[j]+s[j-1],s[j]+a+2*b);
				//两种过河方案:
				//第一种最快的速度两次返航(最快和最慢的过河,返航后和次慢的过河在返航)
				//第二种最快的和次快的过河,最快返航,之后最慢和次慢的过河,然后次快返航。
			 }
					 
		}
	 	printf("%lld\n",sum);
	 }
	 return 0;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值