4人过河问题

来源:互联网 发布:java 并发编程 编辑:程序博客网 时间:2024/05/16 09:15

本文参考http://blog.csdn.net/kaiwii/article/details/8019538 


看完这篇文章中的4人过河问题,第一反应就是拿最小时间的人把所有的人都送到对面,但是算完感觉不怎么对,而且看到作者直接

这样来进行分配,虽然最终的结果的却是比我的算的小,明白自己的答案是错误的,但是不怎么理清楚这时间的节约在哪个地方,看了一会,明白这个的巧妙在于C和D的耗费时间都比较大,所以可以选择将C和D一起过去,节约C的时间,但是又有一个问题,如果对面只有C和D的话,势必C必须要回来,这个则完全没有达到将C的时间节约掉的效果,所以首先将B送过去,在对面则可以让B回来,这个就可以直接将C的时间节约掉了,这个就是这个思路的巧妙之处。

于是作者得出这个结论

所以就进行了分情况讨论

下面附上java翻译的算法

package com.cqut.accrossriver;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/*
 * 过桥问题
         在漆黑的夜里,四位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。
         不幸的是,四个人一共只带了一只手电筒,而桥窄得只够让两个人同时通过。如果各自单独过桥的话,
         四人所需要的时间分别是1,2,5,8分钟;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。
         问题是,你如何设计一个方案,让用的时间最少。
 */
public class AccrossRiver {
    public static void main(String[] args){
        Scanner inputScanner=new Scanner(System.in);
        System.out.print("请输入每人最短时间:");
        String timesString=inputScanner.nextLine();
        double[] times=stringToArray(timesString);
        System.out.println("最小时间为:"+getMinestTime(times));
    }
    
    public static double[] stringToArray(String timesString){
        if(timesString!=null&&!"".equals(timesString)){
            String[] strs=timesString.split(" ");
            double[] timeDouble=new double[strs.length];
            int i=0;
            for(;i<strs.length;i++){
                timeDouble[i]=Double.parseDouble(strs[i]);
            }
            return timeDouble;
        }
        else{
            return null;
        }
    }
    
    public static double getMinestTime(double[] times){
        int size=times.length;
        double sum=0.0;
        int i=0;
        if(size>=4){
            /*
             * 从最大的两个开始和最小的两个分别分两种情况进行比较   
             */
            
            for(i=size-1;i>2;i=i-2){
                double resultTimeOne=times[0]+times[1]+times[1]+times[i];
                double resultTimeTwo=times[0]+times[0]+times[i-1]+times[i];
                if(resultTimeOne<=resultTimeTwo){
                    System.out.println("0把1送到对岸!,耗时 "+times[0]);
                    System.out.println("0回到此岸!,耗时 "+times[0]);
                    System.out.println("1把"+i+"送到对岸!,耗时 "+times[i]);
                    System.out.println("1回到此岸!,耗时 "+times[1]);
                    sum+=resultTimeOne;
                }
                else{
                    System.out.println("0把"+i+"送到对岸!,耗时 "+times[i]);
                    System.out.println("0回到此岸!,耗时 "+times[0]);
                    System.out.println("0把"+(i-1)+"送到对岸!,耗时 "+times[i-1]);
                    System.out.println("0回到此岸!,耗时 "+times[0]);
                    sum+=resultTimeTwo;
                }
            }
        }
        if(i==2){
            System.out.println("2把1送到对岸!,耗时 "+times[2]);
            System.out.println("0到达对岸!,耗时 "+times[0]);
            sum=sum+times[0]+times[2];
        }
        else if(i==1){
            System.out.println("0把1送到对岸!,耗时 "+times[1]);
            sum=sum+times[1];
        }
        else if(i==0){
            System.out.println("0到达对岸!,耗时 "+times[0]);
            sum=sum+times[0];
        }
        return sum;
    }
}

这个算法为什么可以能计算多余4个人的情况呢,表面上我们并没有进行四个人以上的讨论,但是其实多个人的计算和四个人的类似,可以说四个人的计算是多个人的最小计算单位,因为我们每次只是考虑最大  第二大  最小  第二小的计算,而多个人的计算只是四个人的重复计算。



0 0
原创粉丝点击