100层楼,扔两个鸡蛋,寻找使鸡蛋摔碎的楼层最快要扔多少次?

2018-08-11  本文已影响644人  XDgbh

解释:两个鸡蛋一样,只有在达到某个楼层高度时,才会摔碎。可以假设这个摔碎临界楼层是N。

1、最笨的方法——只用一个鸡蛋遍历——N次尝试

2、二分查找——两个鸡蛋,鸡蛋A用来二分尝试,鸡蛋B用来在A摔碎后做局部遍历尝试

可见,用二分法结果很不稳定,特别是N小于50时最糟糕(甚至会比第一种直接遍历的还要多一次)。N越大越好找,需要尝试的次数越少。
如果这个题目换成鸡蛋个数不限制,那就是用二分法最快了。

3、平均分割楼层法——假设总共扔X次,其中鸡蛋A扔了X1次,鸡蛋B扔了X2次

4、假设法——假设最多允许尝试X次,问能尝试到的最高的楼层。

当最高楼层为100时,可列出不等式:最高可能尝试到的楼层X*(X+1)/2 > 100,解出X=14次。这就是最稳定的最快寻找到该楼层的扔鸡蛋次数。也就是说第一次扔鸡蛋要从14楼开始扔。14+13+12+11+...+2+1 = 105层,也就是14次尝试一定可以在1-105层中找到那个第N层。推出了公式X*(X+1)/2后,要想编程求任意总楼层条件下,就都很方便了。

5、动态规划法——找最优解常用方法

在我们编程解决问题的过程中,如果遇到最优问题的时候,往往可以先尝试一下动态规划的方法。而动态规划的方法,首要的我们要找到构成这个最优问题的最优子问题。所以,下面的分析,我们首先尝试动态规划的方法,如何解决这个问题,这也是典型的程序员的思路;其次,在众多的问题当中,有不少可以直接归结为数学方程式,如果我们能够写出数学方程式,那么,答案将是更加的简洁、美妙(比如上一种方法推导出来的公式)。

所以,当第一个鸡蛋,由第i个位置落下的时候,要尝试的次数为f[i]= 1 + max(i - 1, f[n-i])用max是确保一定可以在这么多次内找到。那么对于每一个i对f(i)进行比较,非最小的f(i),就是F{n}的值。状态转移方程如下: F{n} = min f[i] = min(1 + max(i - 1, f[n-i]) ) 其中: i的范围为(1, n), f[1] = 1 完毕。

推广动态规划的方法,可以推广为n层楼,m个鸡蛋。如下分析: 假设f{n,m}表示n层楼、m个鸡蛋时找到最高楼层的最少尝试次数。当第一个鸡蛋从第i层扔下,如果碎了,还剩m-1个鸡蛋,为确定下面楼层中的安全楼层,还需要f{i-1,m-1}次,找到子问题;不碎的话,上面还有n-i层,还需要f[n-i,m]次,又一个子问题。 状态转移方程如下: f{n, m} = min(1 + max(f{i - 1, m - 1}, f{n - i, m}) ) 其中: i为(1, n), f{i, 1} = 1

上一篇 下一篇

猜你喜欢

热点阅读