本文由 @lonelyrains 出品。转载请注明出处。 

文章链接: http://blog.csdn.net/lonelyrains/article/details/46428569

高楼扔鸡蛋问题   这个问题非常有名了  早几年之前面试的时候都遇到过,可是当时也确实没搞清楚怎么做,后来也没管了。今天网上偶然碰到,打算趁这个机会彻底搞清楚,就写一篇博文吧。

网上非常多资料,但我感觉都不太易懂,每一步的推导是为什么。

所以我这里仅仅想写一种比較简单、比較完整的推演流程。

题目描写叙述: (挑了一个比較严谨的描写叙述。问题描写叙述严谨非常重要。不然会影响解题思路)

一幢 100 层的大楼,给你两个鸡蛋. 假设在第 n 层扔下鸡蛋,鸡蛋不碎,那么从前 n-1 层扔鸡蛋都不碎.

这两仅仅鸡蛋一模一样,不碎的话能够扔无数次. 已知鸡蛋在0层扔不会碎.

提出一个策略, 要保证能測出鸡蛋恰好不会碎的楼层,
并使此策略在最坏情况下所扔次数最少.

问题分析:

1)最坏情况下所扔次数最少。比較绕口。想表达的意思是。在不明白知道哪一层会碎的情况下。要找到一种策略,通过最少的试验次数,得到临界楼层(恰好不会碎的楼层)。不明白知道。就须要考虑最糟糕的情况,并且这样的策略与其它策略相比是最糟糕的情况下,最少的试验次数。

2)假设一种扔法:第一个鸡蛋,从50楼扔下去。

假设碎了,第二个鸡蛋必须从1~49层逐层试验。假设第i层为临界层。且i≤49,这个时候,要试验的总次数是1 +(i - 1)。由于必须保证在没找到临界楼层之前,鸡蛋不能碎。假设没碎,则第一个鸡蛋能够接着从75层扔。

由于即使这次碎了,还有个鸡蛋,能够继续逐层试验。对第一个鸡蛋的继续从中间分,就比較合理。

3)假设到代数:假设第一枚鸡蛋扔下去的层数为i,则碎了的情况,须要扔的总次数最糟糕的情况是1 + ( i - 1 );假设没碎,剩下的两个鸡蛋都在,须要扔的次数一定为1 + 用两枚鸡蛋来解决剩下的100 - i层的次数(这个问题跟原题是一样的。可是层数少了一些)。也就是 假设用f ( 100 )表示100层的最坏情况下的最少次数,那么从第i层扔鸡蛋的最糟糕的试验次数是 1+ Max( i - 1, f ( 100 - i ) ),Max表示这两者之间的最大值,是最最糟糕的情况了。

而 f ( 100 ) 就是对全部从1到100的全部i里。 1+ Max( i - 1, f ( 100 - i ) )的值最小的那个。

4)迭代公式: f ( 100 ) = Min ( 1 + Max ( i - 1, f (100 - i ) ) ) .   当中Max是针对的 i-1、 f ( 100 - i ) 两者 。 而Min是针对的全部的从1到100的i。

5)初始状态: 假设有一层,从第一层扔下去,无论碎不碎。最糟糕的情况也仅仅须要推断一次。 即 f ( 1 ) = 1。而如题所述,第0层不会碎,则 不用扔也知道,即f(0) = 0。

6)终于结论:题目变成了分析一个迭代公式的值。翻译成了计算机语言,剩下的就能够交给计算机了。

不须要知道怎么一步步算,这不应该是人干的事。仅仅须要知道已经变成了能够循环递归的算式,能够交给计算机即可了。

// 实现代码   <a target=_blank href="http://blog.csdn.net/lonelyrains">blog.csdn.net/lonelyrains</a>

#include <stdio.h>

// #define MAX((a),(b)) (a)>(b)?

(a):(b)  //注意这里也是常考的一点,应该写成以下的形式
#define MAX(a,b) ((a)>(b)?(a):(b)) int fun ( int layer )
{
if ( layer <= 0 )
{
return 0;
} if ( layer == 1 )
{
return 1;
} int min = layer; // 一栋layer层的大楼试验次数肯定不可能超过layer次。
int temp;
for ( int i = 1; i <= layer; i++ )
{
temp = 1 + MAX(i-1, fun( layer - i ) );
if( min > temp )
min = temp;
} return min;
} int main()
{
int layer = 19;
printf("%d",fun(layer));
return 0;
}

用上面的代码測试了一下,给layer赋值19。即针对一栋19层的大楼来算最坏情况的最少次数。就要非常长时间才干出结果了(果然18层是地狱)....

7)其它扩展:

① 问题的解法不止这一种描写叙述,并且不一定要交给计算机算。由于这样递归算。计算机要累死了。能够优化到用非常easy的数列求和公式得到。

关于怎么来的,有两种思路。能够參考以下的第二个參考链接给出的基于意义的理解。这是一种思路。可是比較难理解。第二种。就是纯粹的组合数学方法。将迭代公式转换成通项公式,这个问题还没找到有人这样写过,可是绝对能够有。

② 问题能够扩展为一栋n层的大楼,有m个鸡蛋。甚至不止一栋,而是p栋。 无论怎么样扩展,问题都能够归为找迭代公式。

这个思路就是动态规划的精髓。

8)參考链接:

http://www.zhihu.com/question/19690210

http://blog.csdn.net/linj_m/article/details/9792821

Google面试题-高楼扔鸡蛋问题的更多相关文章

  1. zstu 4214 高楼扔鸡蛋(google 面试题)dp

    input T 1<=T<=10000 n m 1<=n<=2000000007 1<=m<=32 output m个鸡蛋从1到n哪一楼x扔下去刚好没碎,而再x+1 ...

  2. 高楼扔鸡蛋问题(鹰蛋问题) POJ-3783

    这是一道经典的DP模板题. https://vjudge.net/problem/POJ-3783#author=Herlo 一开始也是不知道咋写,尝试找了很多博客,感觉有点领悟之后写下自己的理解. ...

  3. Google 面试题和详解

    Google的面试题在刁钻古怪方面相当出名,甚至已经有些被神化的味道.这个话题已经探讨过很多次,而科技博客 BusinessInsider这两天先是贴出15道Google面试题并一一给出了答案,其中不 ...

  4. Google面试题之100层仍两个棋子

    一道Google面试题,题目如下:"有一个100层高的大厦,你手中有两个相同的玻璃围棋子.从这个大厦的某一层扔下围棋子就会碎,用你手中的这两个玻璃围棋子,找出一个最优的策略,来得知那个临界层 ...

  5. 数组中第K小的数字(Google面试题)

    http://ac.jobdu.com/problem.php?pid=1534 题目1534:数组中第K小的数字 时间限制:2 秒 内存限制:128 兆 特殊判题:否 提交:1120 解决:208 ...

  6. Google 面试题:Java实现用最大堆和最小堆查找中位数 Find median with min heap and max heap in Java

    Google面试题 股市上一个股票的价格从开市开始是不停的变化的,需要开发一个系统,给定一个股票,它能实时显示从开市到当前时间的这个股票的价格的中位数(中值). SOLUTION 1: 1.维持两个h ...

  7. [CareerCup] 6.5 Drop Eggs 扔鸡蛋问题

    6.5 There is a building of 100 floors. If an egg drops from the Nth floor or above, it will break. I ...

  8. Google面试题:计算从1到n的正数中1出现的次数

    题目: 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次. 找工作,准备看写题目,题目说是Goo ...

  9. Careercup - Google面试题 - 5732809947742208

    2014-05-03 22:10 题目链接 原题: Given a dictionary, and a list of letters ( or consider as a string), find ...

随机推荐

  1. Aspnet_Session

    cmd: aspnet_regsql.exe -ssadd -sstype c -d ZZCasSession -S 192.168.0.3 -U sa -P szhweb2010 <!--会话 ...

  2. 【CodeForces688A】Opponents

    [思路分析] 比较水的模拟题 具体见代码吧 #include<iostream> #include<cstdio> #include<algorithm> usin ...

  3. git的常用命令。。

    git的常用命令.. git help <command>  显示command的help git show  显示某次提交的内容 git show $id git co -- <f ...

  4. 运行Django项目指定IP和端口

    默认IP和端口 python manage.py runserver 指定端口: python manage.py runserver 192.168.12.12:8080 此时会报错,我们需要修改配 ...

  5. Java多线程-synchronized关键字

    进程:是一个正在执行中的程序.每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者叫一个控制单元. 线程:就是进程中的一个独立的控制单元.线程在控制着进程的执行. 一个进程中至少有一个线程 Ja ...

  6. android悬浮球实现各种功能、快速开发框架、单词、笔记本、应用市场应用等源码

    Android精选源码 悬浮球,实现一键静音,一键锁频,一键截屏等功能 一个Android快速开发框架,MVP架构 Android QQ小红点的实现源码 android一款单词应用完整app源码 an ...

  7. Unity引擎的Player Settings介绍

    我用的是unity5.4.3版本的 一.窗口打开: 从菜单栏查看播放器设置,选择 Edit->Project Settings->Player 二.全局设置 第一部分: Company N ...

  8. I2C controller core之Bit controller(04)

    4) detect start/stop condition START- falling edge on SDA while SCL is high;  STOP -  rising edge on ...

  9. Object::connect: No such slot (QT槽丢失问题)

    1.看看你的类声明中有没有Q_OBJECT,并继承public QMainWindow{ 例如: class CPlot: public QMainWindow{ Q_OBJECT 2.你声明的函数要 ...

  10. LoadRunner中遭遇交互数据加密的处理方案

    在使用LoadRunner时,当你录制完脚本后可能会发现在交互的数据中会存在密文,或者当拿到接口文档时就已经明确的描述出了交互数据的加解密方法,你该怎么办? 事实上这样的遭遇如今已经成为了一种常态,发 ...