【转载】 扔鸡蛋问题详解(Egg Dropping Puzzle)

更详细的解答在:http://blog.csdn.net/joylnwang/article/details/6769160

传说中有一道Google面试题是这样的:

你有两个鸡蛋,它们有这样的特性:仅当比某层楼更高摔下时破碎,该层及更低的楼层则毫发无损。毫发无损意味着还可以再次摔下。现在你在一个100层高楼中,要求给出一种策略,用尽量少的实验次数确定这个特定的楼高。1楼就破和100楼都不破也是可能的答案。

编者注:给那些爱“逆向思考”的人的提示:不要考虑末状态速度、重力势能、空气阻力。这是一道数学题。

一只鸡蛋

怎么办?似乎很难着手。既然如此,我们先简化一下问题:如果只有1个鸡蛋,策略是什么?显然,一个鸡蛋时只有一种可能的策略:从一楼开始,逐层实验,直到破了为止。如果不这样做,比如第一次从5楼抛下而破碎,我们不会知道究竟极限楼层是4,3,2,还是1楼就破了。

无数鸡蛋

另一个极端是有无数多个鸡蛋。这时候最佳策略是什么样的呢?显然要用到二分法。先在50层扔一个鸡蛋,若没碎就在75层扔一个,再碎就在(50+75)/2 约为63层扔一个……这肯定是最佳策略了。有些数学常识的各位肯定立即看出来,从n层中找出目标层数的次数为log2 n 次。在题设的例子中鸡蛋的消耗量不会超过log2 100 = 6.644,也就是7只。实际上7只鸡蛋可以在128层楼中找到目标楼层。但要注意,并不是非要消耗7只不可。如果答案是100楼的话,那么1只都不会碎掉。

回到2鸡蛋

现在回到2鸡蛋状态。这个时候再用两分法就不合适了:第一只鸡蛋在50层破掉的话,立即化简为前面讨论过的单鸡蛋状态,逐层实验。最差情况是答案为49层,这样我们要尝试49次!一定有好一点的策略。

既然50层不好,我们10层一次怎么样?先在10层抛一次,若碎了就把问题规模缩小到1-10层,没碎就在20层再抛……直到碎了为止,总可以把问题缩减到10层,再用第二枚鸡蛋逐层尝试。最坏情况仍然是答案为99层的情况。我们用第一枚鸡蛋抛了10次,在第100层碎掉;第二枚从91一直试到99层,共有19次。

这是个不错的进步,还能再少点吗?看看现在的策略。第一只鸡蛋每10层抛一次。大胆一点,每11层抛一次怎么样?最坏结果变成了18次,少了!这鼓励我们每12层抛一次……这样下去,最终的结果会变成什么?

注意到随着第一只鸡蛋实验步进n的增加,有两种相反的趋势。首先,第一只鸡蛋的实验次数减少了。其次,第二只鸡蛋的实验区间增大了(进一步地,也就是实验次数增加了。)这会导致一个后果:如果答案在比较低的楼层,实验次数较少,反之亦然。有没有一个办法可以尽量利用大步进的实验次数减少的优势,又规避区间增长的劣势呢?上面种种细节暗示我们:似乎应该用某种方法将低楼层的好情况与高楼层的坏情况统一在一起。

想要使高低楼层实验次数相同并不是难事。假如第一次在11层,碎了,就把答案锁定在1-10层。若没碎,下一次就不应在22层,因为已经消耗了一次实验次数,所以应在21层开始抛。也就是说,每次抛第一只鸡蛋时比上一次步进缩短一层。

从这个方法出发,我们开始构建终极策略。设第一次在第n层开始,第二次就要在n + (n-1) 层开始,第三次在n + (n-1) + (n-2) 层开始,最后要覆盖100层。这是个简单的算式:

n + (n-1) + (n-2) + (n-3) + (n-4) + … + 1  ≥  100

也就是

n (n+1) / 2  ≥ 100

一个简单的二次函数,最小的正根约为13.651,也就是说,首次应该从14层开始。

2鸡蛋终极策略

现在,我们有了终极策略。将第一只鸡蛋按照下表顺序依次抛下,在它破碎的同时为第二只鸡蛋确定了一个区间,逐次尝试。

DropFloor
#114
#227
#339
#450
#560
#669
#777
#884
#990
#1095
#1199
#12100

这就是终极策略了。可以简单地看出,无论结果是哪层,尝试次数总不会超过14次。

好多鸡蛋,好多楼层

下面来挑战一个更一般的问题:你有k个楼层,e个鸡蛋(取egg的意思,不是2.71828),最佳策略是什么?

刚才2鸡蛋情况都闹了那么半天,这个似乎更加复杂。但是,核心内容都是一样的,就是把最大次数最小化。显然我们无法遍历所有的情况,所以这策略应该以某些原则递归地写出,并用程序解决。这原则是:

当我在第n层抛下一只鸡蛋,会有2种结果:

1.碎了。问题化简为(n-1)个楼层,(e-1)个鸡蛋.

2.没碎。问题化简为(k-n)n-k个楼层,e个鸡蛋。

然后就可以写算法查找了。具体的算法当然不难,我就不贴了(其实也不是我写的),最后可以汇成一张漂亮的图:

其中x轴代表k,纵轴代表最大实验次数。蓝线就是y=x线,也就是鸡蛋数e=1的情况。

显然全是e正比于[Log(k)] 的形式,其中[x]为取上整。希望能够有人给出证明。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值