有四个人夜间过一座独木桥,他们只有一只手电筒。而这

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有四个人夜间过一座独木桥,他们只有一只手电筒。而这相关的知识,希望对你有一定的参考价值。

座独木桥一次最多允许两个人同时通过 ,而且过桥的时候必须持有手电筒,所以就得有人把手电筒带来带去。两人同行时以较慢者的速度为准,他们四个人过桥的时间分别是1分、2分、6分和10分。他们四个人过完桥最少需要几分钟?

1+2过=2分钟 1回头=1分钟6+10过去=10分钟2带回=2分钟1+2过去=2分钟总计=17分钟。

故:(1)1分钟的和2分钟的先过桥(此时耗时2分钟)。

(2)1分钟的回来,(此时共耗时3分钟)。

(3)5分钟的和10分钟的过桥(共耗时2+1+10=13分钟)。

(4)2分钟的回来(共耗时2+1+10+2=15分钟)。

(5)1分钟的和2分钟的过桥(共耗时2+1+10+2+2=17分钟)。

此时全部过桥,共耗时17分钟。

分析:根据要求出四个人过桥最少时间,即可得出应首先让用时最少的两人先过桥,让他们往返送灯会节省时间,进而分别分析得出即可。

解答:根据要求出四个人过桥最少时间,即可得出应首先让用时最少的两人先过桥,让他们往返送灯会节省时间。

参考技术A 1+2过=2分钟
1回头=1分钟
6+10过去=10分钟
2带回=2分钟
1+2过去=2分钟
总计=17分钟(最快了)本回答被提问者采纳
参考技术B 1+2+1+6+1+10=21(分钟)
答:最少需要21分钟。
参考技术C 1和2先过,1带回,6和10过去,2带回,然后和1一起过!
2+1+10+2+2=17
参考技术D 2+1+10+2+2=17肯定对

贪心算法——过河问题

问题: 

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

输入:
  第一行是一个整数T(1<=T<=20)表示测试数据的组数
  每组测试数据的第一行是一个整数N(1<=N<=1000)表示共有N个人要过河
  每组测试数据的第二行是N个整数Si,表示此人过河所需要花时间。(0<Si<=100)
输出:
  输出所有人都过河需要用的最少时间。
样例输入:

1
4
1 2 5 10

样例输出:

17

思路分析:

  我们可以根据示例的输出去反推我们选取的策略是不是最优。先假设这四个人是A、B、C、D。那解这道题的一个很自然的想法就是每次让跑得最快的A陪着另一个过桥,然后A快速地跑回来,再陪下一位过去,最后所有人就都可以过桥了。 让我们来算一下这要多长时间。为了方便起见,我们把旅行者出发的桥的这一边称为“此岸”,而把旅行者想要到达的那边叫“彼岸”。在表达一个过桥方案时,我们用“←”来表示从彼岸到此岸的移动,用“→”表示从此岸到彼岸的移动。前面“A护送大家过河”的方案就可以写成:(右边数字为完成此步骤所需时间)。

    A B → 2 
    A ← 1 
    A C → 5 
    A ← 1   
    A D → 10

  所用时间为2 + 1 + 5 + 1 + 10 = 19大于17说明这种情况下这种策略是不行的。但其实有更快的办法:

    A B → 2 
    A ← 1  
    C D → 10            
    B← 2           
    A B → 2 

  所用时间为2 + 1 + 10 + 2 + 2 = 17与测试用例相吻合说明这这种策略对于这种情况下是适合的。

  这个办法的聪明之处在于让两个走得最慢的人同时过桥,这样花去的时间只是走得最慢的那个人花的时间,而走得次慢的那位就不用另花时间过桥了。那这样的策略是不是就一定适合所有的策略呢,我们在这样的情况下就要多举出几个例子来证明自己的观点。我们可以举出 1 2 2 9 来看下,可以发现第一种方案其实是比第二种方案更快。说明这个跟测试用例的输入是有关系的,我们不知道在什么情况下哪种方案最优所以我们需要将我们自己选择的较优的两种方案进行比较选择出花费时间较少的那组。

代码:

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

public class 快速渡河 {

public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
for (int i = 0; i < T; i++) {
int n = sc.nextInt();
int[] speed = new int[n];
for (int j = 0; j < n; j++) {
speed[j] = sc.nextInt();
}
// 排序
Arrays.sort(speed);
f(n, speed);
}
}

private static void f(int n, int[] speed) {
int left = n;
int ans = 0;
while (left > 0) {
if (left == 1) {// 只有1
ans += speed[0];
break;
} else if (left == 2) {// 只有两人
ans += speed[1];
break;
} else if (left == 3) {// 有三人
ans += speed[2] + speed[0] + speed[1];
break;
} else {
// 12出发,1返回,最后两名出发,2返回
int s1 = speed[1] + speed[0] + speed[left - 1] + speed[1];
// 13出发,1返回,14出发,1返回,12过河
int s2 = speed[left - 1] + speed[left - 2] + 2 * speed[0];
ans += Math.min(s1, s2);
left -= 2;// 左侧是渡河的起点,left代表左侧的剩余人数
}
}
System.out.println(ans);
}

}


结果:

  

总结一下:

  贪心策略简单来说就是出最优的策略,然后再去证明这个策略是否最优,反之换一种策略继续证明,那证明的过程往往是很困难的,我们可以采用反证的方式,然后多举例证明策略是否成立。贪心算法的难点就是选取最优策略,还要判断当前最优是不是整体最。有时候方案只有一种,有时候方案有很多种,很多种的情况下,我们就需要对其进行比较,因为在某些情况下这种策略是最优的,有些情况下,另外一种策略是最优的,通过比较最终得到的肯定是最优的方案。


以上是关于有四个人夜间过一座独木桥,他们只有一只手电筒。而这的主要内容,如果未能解决你的问题,请参考以下文章

转性格测试

夜过吊桥算法

晚上一家人一起过河,需过一独木桥,只有一个手电筒, 过桥最多只能让两个人同时过,过桥必须要带着手电筒

算法也是很过瘾的~~用面向对象实现~夜过吊桥~算法

过桥问题 pascal

和别人发生矛盾怎么办?一个故事醒悟