前言

大一的时候蓝桥杯省赛遇到过(作为非编程题的压轴题),这次看的别人的面经也多次出现,就写篇博文总结一下。

题目

有一栋楼共100层,一个鸡蛋从第N层及以上的楼层落下来会摔破, 在第N层以下的楼层落下不会摔破。给你2个鸡蛋,设计方案找出N,并且保证在最坏情况下,最小化鸡蛋下落的次数。

解析

无脑二分法(最多人想到的伪解法)

当时省赛没注意审题,就想的这种方法,首先需要确定的是,在最坏的情况下,求最小化尝试次数,所以肯定不是无脑二分那么简单了。

例如,你第一次扔第50层,碎了如果你再选择二分,直接到25层又碎的话,两个鸡蛋就都没了,接下来你咋试啊?

所以你接下来只能从1层到49层一个一个试了,最终尝试次数为50次。

假设法

首先,假设答案,也就是最小尝试次数为x,此时从第x层开始扔,有两种情况:

碎了,那么只能从1到x-1一个一个试了,加上前面扔的一次,总结果为x次,符合,这也是为什么选择第x层的原因,如果选择其他层,又碎了的话,则最小尝试次数肯定不等于x,这就与假设相悖了。

没碎,那么直接把第1到x层抛弃掉,当作不存在(因为鸡蛋不会在这范围内碎掉),我们把第x+1层当成第1层,尝试次数为x-1(因为刚刚扔了1次,最小尝试次数减1),此时就从第x-1层(真实层数为x+x-1)开始扔,同样又会出现两种情况:

第二次碎了,则是从第1层到第x-2层开始扔 ,总尝试次数同样是x

第二次没碎,还是之前原理,这次从x-2层开始,以此类推,一直扔到最后一层或碎了为止。

最终结果就是\(x+(x-1)+(x-2)...+1 = 100\),解得\(x = 14\)。

题目升级版本

楼层M,鸡蛋数N,求最坏情况下的最小次数。

动态规划法

理解了上面的假设法,再学过动态规划的话,这里应该就问题不大了。

状态转移方程如下:

\[f[m][n] = min(f[m][n],1+max(f[k-1][n-1],f[m-k][n]),k\in[1,m-1])

\]

解释:当有n个鸡蛋时,所需尝试的楼层数为m,此时将鸡蛋扔在第k层,则有两种情况

碎了,那么接下来只需要尝试1到k-1层,鸡蛋数为n-1,此时问题不就转化成了楼层数k-1,鸡蛋数n-1,求最坏情况下的最小次数吗?

没碎,那么直接把第1到k层抛弃掉,只需要尝试第k+1到m层,鸡蛋没碎,所以扔为n,此时问题不就转化成了楼层数m-k,鸡蛋数n,求最坏情况下的最小次数吗?

为什么取MAX?因为是最坏的情况,所以取碎了与没碎中的最大情况。

代码如下:

int superEggDrop(int egg,int floor){

int ans[floor+1][egg+1];

for(int m = 1;m <= floor;m++)

for(int n = 1;n <= egg;n++)

ans[m][n] = m;//最坏的情况下,自然是所有楼层试一遍,同时这也是鸡蛋数为1时的答案

for(int m = 1;m <= floor;m++)

for(int n = 2;n <= egg;n++)//n必须从2开始,如果是1,就会出现ans[k-1][1-1=0],显然不存在0鸡蛋的情况

for(int k = 1;k <= m-1;k++)

ans[m][n] = min(ans[m][n],1+max(ans[k-1][n-1],ans[m-k][n]));

return ans[floor][egg];

}

然而,该解法的时间复杂度为\(O(km^2)\),空间复杂度为\(O(mn)\),显然还可以继续优化。

动态规划+二分优化

对于\(f[k-1][n-1]\)和\(f[m-k][n]\),当在第三重循环中,\(m,n\)不变,我们可以将其当作系数,只有\(k\)在\([1,m-1]\)的范围内一直增加,而\(k\)又与楼层数有关,显然,当楼层数增加时,测试次数一定增加(100层和101层,显然100更有利吧?)。

而\(f[k-1][n-1]\)和\(f[m-k][n]\),前者\(k\)系数为正,后者\(k\)系数为负,一个递增,一个递减,我们就可以找二分它们的交点,使得无论碎不碎,它们的测试结果都相同,使得时间复杂度为\(O(kmlogm)\)。

int superEggDrop(int egg,int floor){

int ans[floor+1][egg+1];//鸡蛋数只需要考虑两种情况

for(int m = 1;m <= floor;m++)

for(int n = 1;n <= egg;n++)

ans[m][n] = m;//最坏的情况下,自然是所有楼层试一遍,同时这也是鸡蛋数为1时的答案

for(int m = 2;m <= floor;m++)//当楼层数为1时,结果必然是1

for(int n = 2;n <= egg;n++){//n必须从2开始,如果是1,就会出现ans[k-1][1-1=0],显然不存在0鸡蛋的情况

int l = 1,r = m;//范围是[l,r)

while(l+1 < r){

int k = (l+r)/2;

int l_value = ans[k-1][n-1];

int r_value = ans[m-k][n];

if (l_value == r_value){

l = k;

break;

}

else if (l_value > r_value) r = k;

else l = k+1;

}

ans[m][n] = min(ans[m][n],1+max(ans[l-1][n-1],ans[m-l][n]));

}

return ans[floor][egg];

}

当然了,现在还不是最优解,由于时间问题,这里就不再赘述,有兴趣的可以自行百度。

java动态规划鸡蛋问题_动态规划——楼层扔鸡蛋问题相关推荐

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

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

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

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

  3. 动态规划经典题目_动态规划经典题目:鸡蛋掉落(附视频讲解)

    题目: 思路: 先放上视频讲解 动态规划经典题目:鸡蛋掉落https://www.zhihu.com/video/1225199247848513536 纠正:视频里的状态转移方程漏写了一个+1,意思 ...

  4. 动态规划走楼梯_动态规划问题为什么要画表格?

    ❝ 本文是我的 91 算法第一期的部分讲义内容.91 算法第一期已经接近尾声,二期的具体时间关注我的公众号即可,一旦开放,会第一时间在公众号<力扣加加>通知大家. ❞ 动态规划可以理解为是 ...

  5. 面试被问扔鸡蛋问题:100层扔鸡蛋问题(扔球问题)

    题目:两个软硬程度一样但未知的鸡蛋,它们有可能都在一楼就摔碎,也可能从任意层楼摔下来没事. 有座100层的建筑(也可能是其他层数),要你用这两个鸡蛋确定最少尝试多少次,可以找出鸡蛋碎裂的最低层. 解法 ...

  6. java 爬楼梯算法_动态规划-爬楼梯问题java实现

    最近开始看算法导论,研究了一下动态规划,下面就开始直入主题开始记录近期看的第一个知识点动态规划.提起动态规划就不得不提几个动态规划的金典问题爬楼梯.国王金矿.背包问题.今天就仔细分析一下爬楼梯问题. ...

  7. java 动态规划找零钱_动态规划之找零钱问题

    找零钱是一个经典的动态规划问题.这种问题,我建议,首先学会暴力解法,然后从暴力解法中优化出动态规划的解法,这样,更能体会动态规划的魅力. 问题描述 有n种不同币值的硬币,硬币数量无限.给定一个数量T, ...

  8. java经典问题国王_动态规划-国王的金矿问题java

    紧接着上一篇动态规划问题,现在我们开始探讨一个新的问题,问:有一个发现了5个金矿,每一个金矿的储量不同,需要参与挖掘的工人数也不通,参与挖矿工人的总数量是10人,每一座金矿要么全挖,要么不挖,不能派一 ...

  9. java动态规划货车运输_动态规划01背包问题_动态规划方法在配送线路优化中的应用研究...

    [摘要] 应用图论的方法对配送线路进行优化的缺点是,当线路复杂时计算较为烦琐,而应用动态规划的方法能有效解决这个问题.本文从理论上应用动态规划的方法对共同配送线路进行优化,并应用此方法对实际问题进行计 ...

最新文章

  1. PyCharm缺少cv2模块怎么办?怎样在PyCharm中安装自己需要的package?
  2. [云炬python3玩转机器学习笔记] 3-5Numpy数组和矩阵的基本操作
  3. PHP入门04 -- 面向对象程序设计
  4. Apache详细介绍 - [ Apache v2.4.10 for Windows ]
  5. python 去掉文件后缀_python从zip中删除指定后缀文件(推荐)
  6. spring整合使用activemq
  7. 5个让你的404页面变的更加实用的技巧
  8. python counter 出现次数最少的元素_[PY3]——找出一个序列中出现次数最多的元素/collections.Counter 类的用法...
  9. python中bd是什么属性_python数据类型及其特有方法
  10. 一天一种设计模式之三-----单例模式
  11. 书籍推荐:《LInux就该这么学》
  12. HDU2002 计算球体积【入门】
  13. CentOS上安装Selenium和google Driver的过程以及问题记录
  14. 计算机编码器的工作原理,优先级编码器74LS148的电路结构、工作原理及使用方法...
  15. python3 接口获取数据
  16. [渝粤教育] 西南科技大学 管理学原理 在线考试复习资料(6)
  17. C++数组初始化及定义
  18. [转]图像梯度:算子
  19. python生成器与迭代器_python 生成器与迭代器(yield 用法)
  20. 2022全网最全Java面试题-小米社招面试经验java,面试题整理(一面二面)

热门文章

  1. Python opencv3安装
  2. 互联网协议安全IPSec
  3. 华为云服务器上部署war包(虚拟机也同样适用)
  4. 也就是一些简单的分享
  5. Linux下编辑处理数理化公式(转)
  6. 蓝色心情XP主题一键安装包.exe
  7. 软件测试(三):缺陷管理
  8. QGIS实现tiff文件转png、jpg等
  9. 哈工大计算机科学与技术新院长,计算机学院2017级新生开学典礼顺利召开
  10. 对偶单纯形c语言程序,通用对偶单纯形法的C语言程序.doc