Eggs Dropping puzzle(2 eggs, 100 floors)

题目如下:

You are given two eggs, and access to a 100-storey building. Both eggs are identical. The aim is to find out the highest floor from which an egg will not break when dropped out of a window from that floor. If an egg is dropped and does not break, it is undamaged and can be dropped again. However, once an egg is broken, that is it for that egg.

If an egg breaks when dropped from floor n, then it would also have broken from any floor above that. If an egg survives a fall, then it will survive any fall shorter than that.

The question is: What strategy should you adopt to minimize the number egg drops it takes to find the solution?. (And what is the worst case for the number of drops it will take?)

  • 问题一: 只有一个鸡蛋的时候, 如何测试
    如果我们只有一个鸡蛋, 我们知道鸡蛋一旦碎了, 我们就没有鸡蛋了。 所以我们要找出这个使得鸡蛋恰好碎的critital floor楼层, 我们只能从第一层开始向上一层一层的找。
    所以最坏的情况下, 我们需要扔100次才能找到(即要么在100层, 要么在100层也不会碎)。

  • 问题二: 现在我们有两个鸡蛋, 我们该如何测试呢?
    我们可以从第50层开始扔, 这样我们就可以把我们的问题的规模减为一半了。 有两种可能:
    (1)蛋碎了, 我们知道critical floor在50层楼以下。 但是此时我们手里还剩下一只鸡蛋, 我们没有别的办法, 只能从第一层开始一层层的往上找。 最坏的情况下我们需要检查: 1(对应着第一个出师未捷的蛋) + 49 = 50次

    (2) 蛋没有碎。 此时我们比较lucky, 然后继续用这个蛋进行二分测试。
    无论如和, 我们去上述两种情况最坏的情况, 即50次了。

  • 问题三: 能否做的更好
    所以做的更好, 就是我们使得最坏情况下, 扔的次数是最小的。 我们可以选择按照如下的方式扔鸡蛋。
    选择10floor的strategy。 也就是选择第一只鸡蛋:先从10层开始扔, 如果碎了, 就用第二个鸡蛋check 1-9层。 如果没有碎, 继续用这一个鸡蛋从20层开始扔, 一直进行下去。
    最坏的情况下(即最大的扔鸡蛋的次数):
    到90次的时候第一个鸡蛋还没有碎。 但是在100次的时候碎了。然后我们用第二个鸡蛋测试从91层开始, 一层层的测试。 我们的次数是: 10(第一个蛋) + 9 = 19次。
    好的这个策略远好于第一个策略。

  • 问题四: 还能做到更好吗?
    我们可以选择minimization of maxmum regret的策略。

上述的办法是采用的等差数列的方式扔鸡蛋。 现在我们换个策略。 只要我们的第一个鸡蛋不碎, 我们就减少增加的楼层数进行扔鸡蛋。 这样就使得一旦我们的第一个鸡蛋碎了, 那么使用第二个鸡蛋测试所需要的次数的是递减的。 例如第一个鸡蛋在第一层就碎了与第一个鸡蛋在第二层碎了这两种可能对应的导致的第二个鸡蛋的测试次数是递减的。
如何找到第一个鸡蛋最开始的扔鸡蛋的层数。 我们按照如下方式计算出来:
(1)第一个鸡蛋从楼层n开始向下扔, 如果碎了, 使用第二个鸡蛋一层层检查前面(n-1)层楼。
(2)如果第一个鸡蛋没有碎, 那么接下来, 我们从2n - 1层开始往下扔。 也就是说此时我们又向上走了n -1层开始扔第一个鸡蛋。 如果碎了, 用第二个鸡蛋检查前面n -1 层。 没有碎, 继续向下扔第一个鸡蛋。。
(3)第一个鸡蛋没有碎, 在楼层n + n - 1 + n -2 = 3n -3处扔鸡蛋。
依次进行下去。

我们有如下公式:
n + (n-1) + (n-2) + (n-3) + (n-4) + … + 1 >= 100
于是得到:
n (n+1) / 2 >= 100
计算得到:
n = 13.651。
我们取ceiling, 得到n = 14.
所以我们测试的情况如下:


测试情况

最坏的情况是我们扔了14次。 也就是我们第一次扔第一个蛋的时候, 这个悲催的家伙就碎了。 然后我们只能从一层开始向上, 逐层的用第二个蛋检查:
1 + 13 = 14。
下面我们使用动态规划求解这个题。
n个鸡蛋, k层楼。
一个问题要想搭上动态规划这趟高速列车, 那么这个问题的结构必须拥有如下两个优秀的特点。
(1)最优子结构
如果鸡蛋从x层向下扔的时候,会出现两个case:
– case 1: 鸡蛋碎了, 此时我们需要使用剩下的鸡蛋n - 1(假如我们有n 个鸡蛋)个鸡蛋去检查下面的x - 1层楼。

 k ==> Number of floors
 n ==> Number of Eggs
 eggDrop(n, k) ==> Minimum number of trails needed to find the critical floor in worst case.
  eggDrop(n, k) = 1 + min{max(eggDrop(n - 1, x - 1), eggDrop(n, k - x)): x in {1, 2, ..., k}}

(2) 重叠子问题
这个很容易看出来。
算法思路图:

算法思路图

递归版本的编程实现:

        static int max(int a, int b) => a > b ? a : b;

        /// <summary>
        /// Eggdrop the specified n and k.
        /// </summary>
        /// <returns>The eggdrop.</returns>
        /// <param name="n">鸡蛋数</param>
        /// <param name="k">楼层数</param>
        static int eggdrop(int n, int k)
        {
            if (n == 1)
            {
                return k;
            }
            if (k == 0||k==1)
            {
                return k;
            }
            int min = Int32.MaxValue;
            int x, res;
            for (x = 1; x <= k;x++)
            {
                res = max(eggdrop(n-1,x-1),eggdrop(n,k-x));
                if(res<min){
                    min = res;
                }
            }
            return min + 1;
        }

来源

需要注意的是,递归的效率特别慢,我们需要记住一句话,就是:

任何递归都可以用迭代去替换

这里要怎么用迭代去替换递归,我还在思考当中。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,695评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,569评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,130评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,648评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,655评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,268评论 1 309
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,835评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,740评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,286评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,375评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,505评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,873评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,357评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,466评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,921评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,515评论 2 359

推荐阅读更多精彩内容