本文由 @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. Power Network(最大流(EK算法))

    http://poj.org/problem?id=1459 题意:有一个电路网络,每个节点可以产生.传递.消耗若干电量,有点线连接结点,每个电线有最大传输量,求这个网络的最大消费量. 思路:从源点到 ...

  2. Python 38 初识数据库

    数据库 1.什么是mysql,什么是数据库? 文件处理就可以将数据永久存储 问题 1.管理不方便 2.文件操作效率问题 3.一个程序不太可能仅运行在同一台电脑上 提高计算机性能的方式 1.垂直扩展  ...

  3. centos7用rpm安装mysql5.7【初始用yum安装发现下载非常慢,就考虑本地用迅雷下载rpm方式安装】

    1.下载 4个rpm包 mysql-community-client-5.7.26-1.el7.x86_64.rpmmysql-community-common-5.7.26-1.el7.x86_64 ...

  4. Ionic学习记录(一):ionic及cordova安装、创建第一个应用、项目结构

    目录: 一.ionic的安装 二.创建第一个应用程序 三.浏览器中预览应用 四.项目结构 五.添加页面 一.ionic的安装 使用Ionic创建和开发应用程序主要通过Ionic命令行实用程序(“CLI ...

  5. Cracking the Coding Interview 4.8

    You are given a binary tree in which each node contains a value. Design an algorithm to print all pa ...

  6. 查看 Android App 的 versionCode

    有 App 源码时,可以直接查看 AndroidManifest.xml 文件. <manifest android:versionName="1.4" android:ve ...

  7. 【SQL】INTERVAL YEAR TO MONTH 和 INTERVAL DAY TO SECOND

    INTERVAL YEAR TO MONTH: 作为年和月的时间间隔存储 INTERVAL DAY TO SECOND: 作为天.小时.分和秒的时间间隔存储(DAY,HOUR,MINUTE,SECON ...

  8. Java基础学习笔记: 多线程,线程池,同步锁(Lock,synchronized )(Thread类,ExecutorService ,Future类)(卖火车票案例)

    多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念.进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线 ...

  9. 面试官问你:MYSQL事务和隔离级别,该如何回答

    一.事务 事务是由一组SQL语句组成的逻辑处理单元,是满足 ACID 特性的一组操作,可以通过 Commit 提交一个事务,也可以使用 Rollback 进行回滚.事务具有以下4个属性,通常简称为事务 ...

  10. Django基础(二)

    Django基础(二) http://www.cnblogs.com/wupeiqi/articles/4508271.html