手电筒过河

一。问题:

夜晚n位旅行者要过桥,总共只有一个手电筒,一次最多两人过桥,且过桥必须使用手电筒。每位旅行者单独过桥的所需的时间已知,两人结伴渡桥所用的时间为两人中最长的时间。

求解所有人过桥所用的总时间最短是多少。

二。分析:

因为只有一个手电筒,必定有人过桥之后,还要将手电筒送回来。

若n=1,或n=2  所有人直接过河。

若n=3 ,最快的人往返一次把两个人送过去。

若n=4时,假设四人耗时从少到多依次为a ,  b,  y,  z.

  那么有两种方案过河,

  方案一:ab一起过河,a返回,yz一起过河,b返回接a    耗时b+a+z+b+b

  方案二:ay一起过河,a返回,az一起过河,a返回接b    耗时y+a+z+a+b

  这两种方案的末状态一定是:最大的两个已经过河,最小的两个留在河这面

  两方案的时间差为2b-a-y

  当2b>a+y时,采用方案2, 当2b<=a+y时,采用方案1.

若n>4时,该问题相当于两个快的一直在送最慢的两个,因此递归求解,转化成n-2个旅行者的问题。

#include<stdio.h>
#include<string.h>
#include<algorithm>
 using namespace std;
 int p[1100];
 int cmp(int a,int b)
   {
   	return a<b;
   } 
 int Time(int n)
   {
   	if(n==1)   return p[0];
   	if(n==2)   return p[1];
	if(n==3)   return p[0]+p[1]+p[2];
	if(p[1]*2>=p[0]+p[n-2])
	     return 2*p[0]+p[n-1]+p[n-2]+Time(n-2); 
	 else
	     return 2*p[1]+p[0]+p[n-1]+Time(n-2);
   }
   int main()
     {
     	int T;
     	int n;
     	int i,j;
     	scanf("%d",&T);
     	while(T--)
     	  {
     	  	scanf("%d",&n);
     	  	memset(p,0,sizeof(p));
     	  	for(i=0;i<n;i++)
     	  	 {
     	  	 	scanf("%d",&p[i]);
     	  	 }
     	  	 sort(p,p+n,cmp);
     	  	 printf("%d\n",Time(n));
     	  }
     	return 0;
     }

  

posted @ 2017-08-23 22:53  岁月静好--lyr  阅读(1000)  评论(0编辑  收藏  举报