现在的位置: 首页 > 综合 > 正文

acm_47 过河问题

2019年06月13日 ⁄ 综合 ⁄ 共 1697字 ⁄ 字号 评论关闭

过河问题

时间限制:1000 ms
  内存限制:65535
KB
难度:5
描述



漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,N个人一共只带了一只手电
筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,N人所需要的时间已知;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需
的时间。问题是,如何设计一个方案,让这N人尽快过桥。 

输入
第一行是一个整数T(1<=T<=20)表示测试数据的组数
每组测试数据的第一行是一个整数N(1<=N<=1000)表示共有N个人要过河
每组测试数据的第二行是N个整数Si,表示此人过河所需要花时间。(0
输出
输出所有人都过河需要用的最少时间
样例输入
1
4
1 2 5 10
样例输出
17
来源
POJ
上传者

张云聪

简化模型到最后  每次应该是2个人过去 一个人回来  所以每次河对岸应该是最后增加一个人

然后对于每次过河回来的人应该是河对岸的过河速度最快的人

很自然的想到 每次都把最快的人带去 那么让最快的人回来 那么回来的时间最短

但是当n=4的时候 我们可以发现 可能出现问题,就是 我们让最快和次快的人先过河 然后让最快的回来,之后再让2个最慢的人过去,次快的人回来,2个最快的人过去,这样 满足 timer[0]+timer[2]>2*timer[1]的时候之前的结论推翻了,现在我们就该认识的这种情况下我们应该分情况讨论

接下来我们要确认是否还有特殊情况,先思考当有n个人过河,  那么timer[n-1] 这个过河时间 肯定是省不了的,那么我们就应该考虑让船的返回时间最短,现在考虑 n>4的情况, 这样按照上一段的讨论,最慢和次慢的人应该一起分析,最后获取到的时间分别对应着将最慢和次慢的人送到对岸的时间,时间不可缩短,所以最后就可以得出下列程序

import java.util.Arrays;
import java.util.Scanner;

//acm_47
public class PassRiver {

    public
static void main(String[] args) {
         
PassRiver passRiver = new PassRiver();
         
passRiver.solution();
    }

    public void
solution() {
   
    in = new
Scanner(System.in);
   
    int groups =
in.nextInt();
   
    for (int i =
0; i < groups; i++) {
   
   
   
getDate();
   
   
   
System.out.println(handle(num));
   
    }
    }
    Scanner
in;
    int
num;
   
int[]  timer;
    private void
getDate(){
   
    num =
in.nextInt();
   
    timer = new
int[num];
   
   
   
    for(int i =
0 ; i < timer.length;i++){
   
   
    timer[i] =
in.nextInt();
   
    }
   
   
   
   
Arrays.sort(timer);
    }
   
//这里的逻辑是对数据进行处理,准备采用递归的方法,穿进去的是剩余的人数
    private int
handle(int index){
      
switch(index){
      
case 1:
   
   
   return timer[0];
      
case 2:
   
   
   return timer[1];
      
case 3:
   
   
   return
timer[0]+timer[1]+timer[2];
      
}
      
return Math.min(timer[0]+timer[index-2],
2*timer[1])+timer[index-1]+timer[0] + handle(index-2);
    }
}

抱歉!评论已关闭.