zoukankan      html  css  js  c++  java
  • 手电筒过河

    一。问题:

    夜晚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
    ",Time(n));
         	  }
         	return 0;
         }
    

      

  • 相关阅读:
    自己用 python 实现 base64 编码
    PHPStorm 修改类的命名空间
    PHP 发送邮件
    QQ邮箱开通SMTP服务
    Java 驼峰转下划线
    storage.setUserStorage “errcode":87009 "errmsg":"invalid signature
    window下 phpstorm 打不开
    VBS 去除文件夹下 Excel 的公式
    HTTPS 验证访问略记
    Ubuntu 搜狗输入法输入异常
  • 原文地址:https://www.cnblogs.com/lyr2015/p/7420683.html
Copyright © 2011-2022 走看看