摔鸡蛋问题
问题是 有两颗鸡蛋 在第n层不会碎 n+1层会碎 n就是临界楼层 现在需要给出一种找到临界楼层的方案 使得最坏情况下尝试次数最少
第一次看到这个题目 可能有点摸不着头脑
那我们可以从一种最最常规的方案入手
拿着鸡蛋从第一层逐层往上试 该方案肯定可以试出来 那么考虑最坏情况也就是试到100层 需要100次
该方案有两个问题
一个是最坏情况需要尝试次数太多
另一个是只用了一个鸡蛋
但是我们通过这个方案大概了解了问题
我们有两个鸡蛋 必须充分利用这两个鸡蛋来减少次数 如何利用是一个问题
另外 要注意找的是最坏情况 言外之意是方案需要应对临界楼层出现的所有情况 每种情况方案都对应一个次数 现在要所有情况所需次数中的最大值最小化 这是另一个难点
现在看第二种方案
用第一颗鸡蛋在50层试 如果碎了 就从第一层逐层试 如果没碎 再从剩余的50–100的中间即75层试 以此类推
该方案已经利用了两颗鸡蛋的条件 最坏情况发生在临界楼层就是50 此时第二颗鸡蛋需要从1试到49 再加上第一颗鸡蛋的一次 共需要50次
这个方案已经减少了一半 同时我们也发现了鸡蛋使用的方法 第一颗鸡蛋用来进行范围排除 如果没碎 那么下面的楼层就都不用试了 第二颗鸡蛋用来精确的测试 就也就是第一颗碎了的时候 需要从一个安全点逐层往上试
再进一步分析 次数由第一颗鸡蛋的排除次数加上第二颗鸡蛋的逐层尝试次数得到 这个和是需要优化的 上面的方案就是第一颗鸡蛋排除的范围太大 导致碎了以后第二颗鸡蛋需要尝试的次数太多 但是呢 如果排除范围太小了 第一颗鸡蛋尝试的次数又会变多 所以我们需要优化第一颗鸡蛋的排除范围
再看下面的方案
第一颗鸡蛋的尝试次数为10,20,30。。。100,也就是10的倍数。最坏情况发生在临界楼层是99的情况。第一颗鸡蛋次数为10次,第二颗从91一直试到99,共需要19次。
这个方法进一步把最坏情况次数减少到了19次。
但是始终是靠试的办法,而且每一次排除的楼层数是固定的。
下面就从理论分析的角度来计算出最优解。
假设最优方案的最坏情况需要尝试x次。
那么第一颗鸡蛋需要从x楼层尝试。为什么?
假如在比x高的楼层尝试,比如y=x+1,如果碎了,第二颗鸡蛋最多需要需要y-1=x次,加上第一颗鸡蛋的一次,就需要x+1尝试才能找到,这与假设矛盾(最坏只需要x次)。或者说,我们设定从x层开始尝试,就是为了保证x碎了以后,第二颗鸡蛋逐层试,总共最多需要x次。也就是保证了前面提到的“和”的第一部分满足条件。那如果在比x低的楼层试呢?没有最大化第一颗鸡蛋的作用。因为在x层试可以满足最坏情况的假设,且可以排除最多的楼层数,就没有理由在更低的楼层试。
那如果在x楼层没碎,第二次又该在哪里试?
剩余100-x楼层,总的尝试机会变成了x-1次,仍然按照之前的思路,需要在剩余的楼层的x-1层试。假设又碎了,总的次数为x-2+1+1=x次,也满足。
以此类推,如果没碎,第一颗鸡蛋试的楼层的范围为:x,x-1,x-2,x-3。。。
按照这个思路,只要第一颗鸡蛋在某一层碎了,总的尝试次数都可以保证在x次。
如何求解x?
别忘了我们的楼层总数是100.
所以之前的楼层范围必须覆盖到100层。x+(x-1)+(x-2)+...>=100,进一步求解得到x=14.
所以方案为:在14,27, 39, 50, 60, 69, 77, 84, 90, 95, 99, 100层试第一颗鸡蛋,碎了再逐层试。
该问题也有动态规划解法:
f(x) = min{max(i - 1, f(x - i)) + 1}, 1 <= i <= x
x是楼层数。
因为是最坏情况,所以需要考虑1-100所有情况,i的范围就是1到x。如果i层没碎,相当于找f(x - i),如果碎了,至多再试i - 1.