这个问题是一个印度朋友问我的。

已知有e个鸡蛋,f层楼。问题是尽可能少的尝试,找出扔出鸡蛋不破的最高的楼层。

最开始我的思路是,如果只有一个鸡蛋,f层楼,毫无疑问,只能从一楼到二楼到三楼...依次尝试,这样f层楼最坏的情况下要进行f次尝试。为什么要考虑最坏的情况,因为我们要确保该结果包含所有可能的情况,下面再详细说。然后我分析两个鸡蛋,f层楼。然后我发现,如果有两个鸡蛋,就可以从第2层楼开始扔:如果破了,在用剩下的1个鸡蛋检查1楼;如果没破,两个鸡蛋升至4楼检查同理。如果有3个鸡蛋,f层楼,可以从4楼开始检查:如果破了,2个鸡蛋退至2楼检查同上;如果没破,3个鸡蛋升至8楼检查同理。这样我能确保在耗尽所有鸡蛋的同时,发现最高的楼层。然后开始选择楼层是2的e-1次方,e是鸡蛋的数量,如果不破,继续上升2的e-1次方,破了下降2的e-2次方。。。虽然麻烦点儿,但是理论可行,代码实现也没有问题。

然后我很高兴的告诉印度朋友我解决了这个问题。印度朋友听完我的解释后说跟标准答案不一样。后来一经分析,他指出了这个方法的破绽,我太天真,这个方法是没问题,可以发现扔鸡蛋不破的最高楼层,但并不是最少的尝试。

然后告诉我这个题是有关动态规划。动态规划就是大量递归,但是存在重复计算,因此在开始递归的时候把结果保存在表里面,这样下次用到直接从表里面找不用再次计算,稍微快一点。

然后了解的官方的解释。假设有f层楼,e个鸡蛋。我们用一个表达式E(f, e)来表示这个扔鸡蛋问题的最优答案,即:在有n个鸡蛋f层楼的情况下,找出扔鸡蛋不破的最高楼层的最少尝试次数。然后开始考虑,首先从那一层楼开始扔,结果最佳?前面我尝试过从2的e-1次方层开始仍,但印度老哥已经证明这个方法有问题。所以,该从哪里扔?答案是不知道,至少我不知道。但是我知道计算机速度很快,我们完全可以枚举出所有的可能,然后从里面找出最优解。那就行了,假设先从k层楼往下扔,答案是多少?首先来到k层,扔出去鸡蛋,进行了1次尝试。然后需注意,扔出去鸡蛋的时候,会产生两种结果,一种是鸡蛋破了,一种鸡蛋没破。这两种情况实际只有一种情况会发生。但是我们应该考虑最坏的情况,也就是上界,确保这个上界能够cover两种情况。首先鸡蛋破了,我们知道还剩下e-1个鸡蛋,还知道最高的楼层肯定在k层以下,但不知道就那一层,所以这个时候用E(k-1, e-1)来表示后面最后的操作。如果没破,知道手里还有e个鸡蛋,而且最高楼层肯定在k层以上,只需检查以上的楼层,那就是E(f-k, e)来表示后面的最后操作。所以在k层开始仍的最优解是1+max(E(k-1, e-1), E(f-k, e))。然后因为我们有f层,所以k的值就是从1到f,也就是我们在先从那层楼开始仍这一问题上有f个选择,都可以用递归表达式表示出来。然后我们要做的就是从里面找出最小值,就是E(f, e)的最终答案。

熟悉递归的朋友肯定知道,我们必须知道base case的具体数,不然没法用递归。这里的base case有两个:如果有1个鸡蛋,f层楼,结果会是多少?是f;如果有e个鸡蛋1层楼,结果是多少?是1。然后就行了,有了base case,有了递归表达式,这个问题就解决了。

然后我是用了一个二维数组做记录,比纯递归能快多少没研究,不过总体效率不高。以后有空会去看一下官方的解法,目前没兴趣。基本跟二叉树的写法差不多。印度老哥号称深谙这“简单的 ”二叉树,结果连这个递归写不出来。不懂装懂的人还是挺多。

public class EggDrop
{private int[][] resultSet;private int floor;private int egg;public EggDrop(int floor, int egg){resultSet = new int[floor+1][egg+1];this.floor = floor;this.egg = egg;for(int i = 0; i < egg+1; i++){resultSet[0][i] = 0;resultSet[1][i] = 1;}for(int j = 0; j < floor+1; j++){resultSet[j][0] = 0;resultSet[j][1] = j;}}public int minTry() { return minTry(floor, egg); }private int minTry(int floor, int egg){if(floor == 0 || egg == 0 || resultSet[floor][egg] != 0)return resultSet[floor][egg];int min = Integer.MAX_VALUE;for(int i = 0; i < floor; i++){int temp = 1 + Math.max(minTry(floor-i-1, egg-1), minTry(i, egg));if(temp < min) min = temp;}resultSet[floor][egg] = min;return min;}public static void main(String[] args){int floor = 20;int egg = 8;EggDrop eggDrop = new EggDrop(floor, egg);System.out.println(eggDrop.minTry());int count = 0;for(int i = 0; i < floor+1; i++){for(int j = 0; j < egg+1; j++){if(count < egg){count++;System.out.print(eggDrop.resultSet[i][j] + " ");}else{System.out.println(eggDrop.resultSet[i][j]);count = 0;}}}}
}

扔鸡蛋问题-动态规划相关推荐

  1. 高楼扔鸡蛋问题 - 动态规划+反推演绎

    对于高楼扔鸡蛋问题,本文尝试反其道而行之:首先描述一个普适的高楼扔鸡蛋问题,然后利用动态规划法解决扔鸡蛋次数的问题,最后由获取次数的答案反推出扔鸡蛋的方法. 这种由次数答案反推出方法的演绎方式令人有点 ...

  2. 扔鸡蛋问题 动态规划大法

    之前有一篇文章"扔鸡蛋问题",写的是指定鸡蛋个数在指定楼层,求最优解.里面列举了二分法.平方根法和解方程法,但是,如果鸡蛋个数和楼层数是待定的,那这三种方法都搞不定了.所以,这里又 ...

  3. 每日一道算法题:高楼扔鸡蛋问题(动态规划问题)

    题目是这样:你面前有一栋从 1 到N共N层的楼,然后给你K个鸡蛋(K至少为 1).现在确定这栋楼存在楼层0 <= F <= N,在这层楼将鸡蛋扔下去,鸡蛋恰好没摔碎(高于F的楼层都会碎,低 ...

  4. java动态规划鸡蛋问题_动态规划系列/高楼扔鸡蛋问题.md · lipengfei/fucking-algorithm - Gitee.com...

    # 经典动态规划问题:高楼扔鸡蛋 今天要聊一个很经典的算法问题,若干层楼,若干个鸡蛋,让你算出最少的尝试次数,找到鸡蛋恰好摔不碎的那层楼.国内大厂以及谷歌脸书面试都经常考察这道题,只不过他们觉得扔鸡蛋 ...

  5. 动态规划与数学方程法解决楼层扔鸡蛋问题

    1.问题描述 两个软硬程度一样的鸡蛋,它们有可能都在一楼就摔碎,也可能从一百层楼摔下来没事.有座100层的建筑,用这两个鸡蛋确定哪一层是鸡蛋可以安全落下的最高位置,可以摔碎两个鸡蛋,求给出一个最佳策略 ...

  6. 彻底搞懂-扔鸡蛋问题-方程-动态规划

    1.题目: 2个鸡蛋,从100层楼上往下扔,以此来测试鸡蛋的硬度,比如鸡蛋在第9层没有摔碎而在第10层摔碎了,那么鸡蛋不会摔碎的零界点就是9层,如何用最少的尝试次数,测试出鸡蛋不会摔碎的临界点? 2. ...

  7. 高楼扔鸡蛋问题-经典动态规划

    文章目录 1. 高楼扔鸡蛋 2. 猜数字大小 1. 高楼扔鸡蛋 给你 k 枚相同的鸡蛋,并可以使用一栋从第 1 层到第 n 层共有 n 层楼的建筑. 已知存在楼层 f ,满足 0 <= f &l ...

  8. 动态规划之扔鸡蛋(或手机)问题

    引入 有2个鸡蛋,从100层楼上往下扔,以此来测试鸡蛋的硬度.比如鸡蛋在第9层没有摔碎,在第10层摔碎了,那么鸡蛋不会摔碎的临界点就是9层. 问:如何用最少的尝试次数,测试出鸡蛋不会摔碎的临界点? 分 ...

  9. 扔鸡蛋问题-方程-动态规划

    参考:程序员小灰 https://blog.csdn.net/weixin_40564421/article/details/78988078 题目:2个鸡蛋,从100层楼上往下扔,以此来测试鸡蛋的硬 ...

最新文章

  1. centos 7 安装 Vue
  2. GridView的多主键(Key)取值问题
  3. 在每天下午5点使用计算机时,网络信息安全知识网络竞赛试题(附答案)讲解学习...
  4. 从Java新手到大神需要学哪些知识?
  5. 曾经想学很多很多,最后发现自己只能专心学那么很少的几个必杀技
  6. MAC下MongoDB的安装启动及停止
  7. 数据结构学习笔记(树、二叉树)
  8. php伪静态规则生成,SEO工具箱:PHP自动生成PHPCMS伪静态规则.htaccess
  9. windows phone笔记
  10. 服务器系统2003资源监视器在哪里,Win10资源监视器在哪 如何打开资源监视器
  11. Word撤销键(Ctrl+z)无效的解决方法
  12. 根据26字母排列来搜索排列全国城市
  13. 读书笔记:《我们身在何方?》
  14. WIN7 通知栏处喇叭上有个小红叉,提示未插入“未插入扬声器或耳机”的解决方法
  15. spring cloud 实现服务不间断
  16. kubernetes的ingress:Ingress controller,traefik
  17. 什么是模块化?为什么要模块化
  18. PRD:云迹扶教APP(项目经历)
  19. 微信企业号开发三:主动调用模式之发送news消息
  20. CFA一级学习笔记--权益(六)--权益类证券概述

热门文章

  1. 【备品备件】测试环境,生产环境以及打包部署
  2. java 图片请求_java中使用scoket模拟http post请求发送图片或文件
  3. 嵌入式PROFIBUS DP从站接口模块
  4. 重磅消息Apache Flink 1.9.0隆重发布
  5. _api_attactbs_js__WEBPACK_IMPORTED_MODULE_0__ is not a function
  6. html播放flv直播源,如何使用flv.js直播(pc端)?
  7. Scrapy-Redis分布式爬虫框架详解-邮乐网(ule.com)
  8. 程序员的副业:写了一个专栏《Vue 3企业级项目实战》
  9. 2022年最新广东建筑安全员(安全员ABC证)模拟题库及答案
  10. 小程序关于ios与安卓时间转换问题