问题:某夜,有个团伙要过桥,该桥每次只能通行2个人,只有一个手电筒,过桥必须持有手电筒。
这些人单独过桥的时长分别为t1、t2、t3、t4、t5 ……tn。
这些人单独过桥的时长分别为t1、t2、t3、t4、t5 ……tn。
谁能设计程序计算出这伙人过桥需要的最短时间?
解题思路:两种方案过桥
2t1 进行对比 t1+t(n-1);
1、12充当运输车的作用,每次1,2 去,1回,另外的去,2再回(2t1 < t1+t(n-1))
2、1充当运输车,每次都和另一个人走,1回来(2t1 > t1+t(n-1))
public static void GoThroughBridge() {
System.out.println("请输入过桥的人数");
Scanner scan = new Scanner(System.in);
int N = scan.nextInt();
int[] arr = new int[N];
System.out.println("请输入每个人过桥的时间");
for(int i = 0;i<N;i++) {
arr[i] = scan.nextInt();
}
//把过桥的时间从小到大排序
Arrays.sort(arr);
/*
* 做题的时候用的是数组,所以a1 对应的是arr[0]
* */
//执行的总时间
int totalTime = 0;
//false 为单人运,true 为双人运
boolean flag = false;
//每次需要比较的是 2a2 == a1+a(n-1);
if(N==1) totalTime = arr[0];
else if(N==2) totalTime = arr[1];
else if(N==3) totalTime = arr[0] +arr[1] + arr[2];
else {
//等式左边的值是固定的
int left = 2*arr[1];
//a1,a2 走的时间
int usualTime = arr[0]+arr[1];
for(int i = 0;i<(N-2)/2;i++) {//走的来回次数
//数组是从0开始的所以要减两次1
if(2*arr[1] <arr[0]+arr[N-2*i-1-1]) {
totalTime += usualTime;//a1,a2走的时间包括a1返回
totalTime += arr[N - 2*i - 1] + arr[1];//最慢两个人走的时间,包括a2返回
}else {
//这里运用了类似递归的方法,每次只计算2个
totalTime += arr[0] * 2;
for (int j = N - 2*i -2 ; j <= N - 2*i -1; j++){
totalTime += arr[j];
}
flag = true;
if(N - 2*i - 1 <= 1) {
break;
}
}
}
if (1 == N % 2){
totalTime += arr[0] + arr[1] + arr[2];
}
if(0 == N % 2){
totalTime += arr[1];
}
}
System.out.println(totalTime);
}
刚开始做这个问题的时候感觉很难,但是和同学讨论了一会儿就感觉懂了,我们一起写,他用的是递归的方式,感觉用递归的方式比我的方式简单,但是我这种方式也是看过了一篇文章才有的灵感,模仿人家写的。