POJ1700 Crossing River

       题目大意:有n个人要过河,然后只有一艘船并且最多承载两人。每个人过河都需要花费一定的时间,如果两人同时间过河以花费时间多的为准。 

      现在就问你采取怎样的方法能使n个人在花费最短的时间内全部过河。通过分析题目我们可以得出我们大体可以用两种方法来使n个人过河:

      1〉最小的和次小的先过河,最小的划船回来让最大的和次大的划船过去,而后次小的再将船划回来。。。

     2〉最小的和最大的先过去,然后再回来接次大的,以此类推。。。

     特殊情况:当n=3时,不管哪种方法只要三人要全部过河,时间肯定是sum=n1+n2+n3

                         n=2,肯定是取其最大者。。n=1就更不用说了!

      每一趟(来回)n-=2;此题DP,贪心都可,以过河的时间为核心价值!

     如此一来我们只需比较在n个人时这两种方法的优越性就可以了。输入结束后,将存放每个人过后花费时间先排序,便可轻易实现上述的功能。

    具体代码实现如下:

Crossing River
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 12171 Accepted: 4610

Description

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

Source

#include<iostream>
#include<algorithm>
#define N 1005
using namespace std;
int a[N];
int main(){
  int T,n,i,sum;
  cin>>T;
  while(T--){
	sum=0;
    cin>>n;
	for(i=0;i<n;i++)
	  cin>>a[i];
	sort(a,a+n);
	for(n;n>3;n-=2){
	   if((2*a[1]+a[0]+a[n-1])>(2*a[0]+a[n-1]+a[n-2]))
		   sum+=(2*a[0]+a[n-1]+a[n-2]);
	   else
		   sum+=(2*a[1]+a[0]+a[n-1]);
	}
	if(n==3)
		sum+=a[0]+a[1]+a[2];
	else if(n==2)
		sum+=a[1];
	else if(n==1)
		sum+=a[0];
	cout<<sum<<endl;
  }
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值