题目链接:http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=26251
题意 :
有N个人想要过河,但是只有一条船,且船每次最多载2个人,而每次必须有个人把船开回来。每个人过河都会有不同的时间,当两个人一起过河时,过河时间
为更慢的那个人的,即两个数中取更大的那个数,你所要做的是求出在这N个人中总共过河的最短时间。
案例:
input
1
4
1 2 5 10
output
17
题目分析:
每次都要尽量让最快的人把船开回来,要先进行排序。
对n(n>3)个人来说,要将用时最长的两人X、Y过河,有两种方按。
已知:TimeOfA<=TimeOfB<=TimeOfX<=TimeOfY
<1> 将用时最短的两个人A、B先过河,然后A划船返回,然后A下船,X、Y过河,B划船返回。该方案耗时:
TimeOfA+TimeOfB+Max(TimeOfA,TimeOfB)+Max(TimeOfX,TimeOfY)=TimeOfA+2*TimeOfB+TimeOfY.
<2> A与Y过河,A划船返回;A与X过河,A划船返回。耗时为:
Max(TimeOfA,TimeOfX)+TimeOfA+Max(TimeOfA,TimeOfY)+TimeOfA=2*TimeOfA+TimeOfX+TimeOfY.
在<1>、<2>方案中选择耗时最小的,然后递归。
不管用哪种方法算出的时间都不是所有的案例的最少的时间,所以需要把两种方法合并起来,而两种方法排完序的前三个数的方法一样,所以循环条件为k>2,
再对于k==0,k==1,k==2分开讲。
源代码如下:
1 #include<iostream> 2 #include<algorithm> 3 #define max 1000 4 using namespace std; 5 int main() 6 { 7 int T,N,a[max],k,n,m,s; 8 cin>>T; 9 for(int i=0;i<T;i++) 10 { 11 s=0; 12 cin>>N; 13 for(k=0;k<N;k++) 14 cin>>a[k]; 15 sort(a,a+N); 16 for(k=N-1;k>2;k=k-2) 17 { 18 n=a[0]+2*a[1]+a[k]; 19 m=2*a[0]+a[k]+a[k-1]; 20 if(n>m) 21 s+=m; 22 else 23 s+=n; 24 } 25 if(k==0) 26 s=a[0]; 27 else if(k==1) 28 s+=a[1]; 29 else if(k==2) 30 s+=a[1]+a[2]+a[0]; 31 32 cout<<s<<endl; 33 } 34 return 0; 35 }