本文由 @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. nodejs express开发

    用NodeJS+Express开发WEB应用---第一篇 大漠穷秋2014-03-28 预热 为了对后面的内容理解更加透彻,推荐首先阅读下面这篇很好的文章: http://www.nodebeginn ...

  2. 洛谷P1894 [USACO4.2]完美的牛栏The Perfect Stall(二分图)

    P1894 [USACO4.2]完美的牛栏The Perfect Stall 题目描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星 ...

  3. js点击特效

    //点击效果博客页面点击就可以看到 <script type="text/javascript"> !function(e, t, a) { function n() ...

  4. Nginx代理配置-centos6.10版

    nginx代理配置 cd /etc/nginx/init.d vi default.conf 添加: upstream server1{ server 192.168.125.128:8100 wei ...

  5. BZOJ 4525 二分

    思路: 满足二分性质... 二分一下      就完了 //By SiriusRen #include <cstdio> #include <algorithm> using ...

  6. https 结合使用 对称加密和非对称加密

    (一)对称加密(Symmetric Cryptography) ---共享密钥加密 对称加密是最快速.最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥( ...

  7. 连接Oracle数据库帮助类

    连接Oracle数据库帮助类,就是把连接Oracle数据库的方法封装起来,只需要在其它页面调用就可,不需要重复写. import java.sql.Connection; import java.sq ...

  8. CXF-JAX-WS开发(二)spring整合CXF-JAX-WS

    一.服务端 1.目录结构 2.创建maven工程[Packaging:war] 3.引入依赖 <dependencies> <!-- CXF(这里不需要引入cxf-rt-transp ...

  9. Javascript语法,变量类型,条件,循环语句,函数,面向对象

    1.JavaScript代码革两种存在形式: <!-- 方式一 --> <script type='txt/javascript' src='/js/comment.js'>& ...

  10. 一个完整的Appium手机自动化测试实例

    实现过程: 1.使用环境 appium .安卓SDK .python 本文重点是自动化实例,环境搭建过程省略. 2.找到被测APP的包名和Activity Name 手机连接上电脑后,在DOS环境先使 ...