1、题目:

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

2、解决思路

2.1、最笨法:

把其中一个鸡蛋从第1层开始往下扔,如果第1层没碎换到第2层扔,如果第2层没碎换到第3层扔,,,如果第59层没碎换到第60层扔,如果第60层碎了,说明不会摔碎的临界点是59层,最坏情况下需要扔100次

2.2、二分法:

把鸡蛋从50层往下扔,如果第一枚在50层碎了,就从第1层开始(一共只有两个鸡蛋,第一个鸡蛋碎了,第二个鸡蛋就只能用最保守的方式一层一层扔,假如第二个鸡蛋从25层扔,碎了,就无法判断临界点了);如果没碎,继续使用二分法,在剩余楼层的一半(75层)往下扔,,,,最坏需要尝试50次

2.3、平方根法:

做一个平方运算,100的平方根是10,因此我们尝试每10层扔一次,第一次从10层扔,第二次从20层扔,第三次从30层,,,一直到100层,最好情况是在第10层碎掉,尝试次数为1+9=10次;最坏情况是在第100层碎掉,尝试次数为10+9=19次

2.4、方程法:将思路逆转

假设问题存在最优解,这个最优解的最坏情况尝试次数是x次,那么我们第一次扔鸡蛋该选择哪一层?

答案是从第x层开始,选择更高一层或更第一层都不合适

分析:假设第一次扔在第x+1层,如果第一个鸡蛋碎了,那么第二个鸡蛋只能从第1层一层一层扔,一直到第x层,这样总共扔了x+1次,和假设尝试x次相悖,由此可见,第一次扔的楼层必须小于x+1次

假设第一次扔在第x-1层,如果第一个鸡蛋碎了,那么第二个鸡蛋开始一层一层扔,直到第x-2层,这样我们总共扔了x-1次,虽然没有超过假设次数,但似乎有些过于保守(什么意思,还没理解)

假设第一次扔在第x层,如果第一个鸡蛋碎了,那么第二个鸡蛋开始一层一层扔,一直到第x-1层,共x次

因此要向尽量楼层跨度大一些,又保证不超过假设的尝试次数x,那么第一次扔鸡蛋的最优选择就是第x层

更进一步。。。

如果第一次扔鸡蛋在第x层,但并没有打碎,第二次扔鸡蛋在哪一层?

如果第一次扔鸡蛋没碎,我们的尝试次数消耗了一次,问题就转为,两个鸡蛋在100-x层楼往下扔,要求尝试次数不得超过x-1次,则第二次尝试的楼层跨度为x-1层,绝对楼层是x+x-1层;如果还没碎,第三层楼层跨度是x-2,第四层是x-3!

so,x+(x-1)+(x-2)+...+1=100,左边多项式是各次扔鸡蛋的楼层跨度之和,假设尝试x次,所以该多项式共有x项,右边是总的楼层数100,解方程可得x=14((x+1)*x/2=100)

因此,最优解在最坏情况的尝试次数是14次,第一次扔鸡蛋的楼层也是14层,在第一个鸡蛋没碎的情况下,尝试的楼层为:14,27,39,50,60,69,77,84,90,95,99,100,假如鸡蛋不会碎临界点在65层,那么依次:14,27,50,60,69碎了,让后第二个鸡蛋从61层开始61,62,63,64,65,66碎了,即不会碎的临界点是65层

3、动态规划解题:有M层楼N个鸡蛋,找到鸡蛋摔不碎的临界点,需要尝试几次?

可以把m层楼和n个鸡蛋的问题转化为一个函数F(m,n),其中楼层数m和鸡蛋数n是函数的两个参数,函数的值则是最优解的最大尝试次数,假设第一个鸡蛋扔出的位置在第x层(1<=x<=m),会出现两种情况:

1).第一个鸡蛋没碎,则剩余m-x层楼和n个鸡蛋,F(m-x,n)+1

2).第一个鸡蛋碎了,则从1到x-1层尝试,剩余鸡蛋n-1,F(x-1,n-1)+1

so,我们要求m层楼n个鸡蛋条件下,最大尝试次数的最小解,即

F(m,n)= Min(Max(F(m-x,n)+1,F(x-1,n-1)+1)) . 1<=x<=m

3.1、eg:3个鸡蛋,4层楼

首先填充第一个鸡蛋在各个楼层的尝试次数,以及任意多鸡蛋在1层楼的尝试次数,原因:只有一个鸡蛋,so只能从1层扔到最后一层,尝试次数为楼层数量;只有一个楼层,无论有几个鸡蛋,也只有一种扔法,尝试次数只能为1

2个鸡蛋2层楼,带入状态转移方程式F(2,2)=Min( Max(F(2-x,2)+1,F(x-1,2-1)+1)) )

x可以为1和2,so:

x=1时,F(2,2)=Max(F(2-1,2)+1,F(1-1,2-1)+1))=Max(F(1,2)+1, F(0,1)+1)=Max(1+1, 0+1)=2

x=2时, F(2,2)=Max(F(2-2,2)+1,F(2-1,2-1)+1))=Max(F(0,2)+1, F(1,1)+1)=Max(0+1, 1+1)=2

取最小值即为2

依次类推

先上代码(当然了,还是别人写的,看的可真费劲,话说动态规划看一次不懂一次。。。)

3.2、python版代码解决floor层楼仍egg个鸡蛋的问题

# 我们要求m层楼n个鸡蛋条件下,最大尝试次数的最小解,即
# F(m,n)= Min(Max(F(m-x,n)+1,F(x-1,n-1)+1)) . 1<=x<=m
import numpy as npdef get_min_floor(floors=100, eggs=2):# 第一步,创建动态规划的备忘录,即状态转移矩阵f = np.zeros((eggs+1, floors+1), dtype=np.int)# 第二步,考虑边界# part1: 先考虑eggs边界,eggs为0,则为0;eggs为1,肯定从第0层往上依次实验for i in range(floors+1):f[0][i] = 0f[1][i] = i# part2: 再考虑floor的边界,floors为0即为0,floors为1即为1for i in range(eggs+1):f[i][0] = 0f[i][1] = 1# 第三步就是状态方程了,鸡蛋从第2个开始算,楼层也从第2开始算for egg in range(2, eggs+1):for floor in range(2, floors+1):# 你还有egg个鸡蛋,一共有floor层楼的子问题# 定义一个变量来存储最终结果,找到在哪里扔能达到所扔次数最少的目标result = 100000# 从第drop层扔鸡蛋for drop in range(1, floor+1):# 碎了,剩下的问题即如何在drop-1层,用egg-1个鸡蛋寻找最优解broken = f[egg-1][drop-1]# 没碎,在floors-drop层,用egg个鸡蛋找最优解unbroken = f[egg][floor-drop]# 两种情况取最大值,因为我根本不知道鸡蛋会不会碎condition = max(broken, unbroken)+1# 不断和上一次结果做比较,得到最少的扔次数result = min(condition, result)f[egg][floor] = result# 以上步骤在不断的往状态举证填充,到这里已经填充完毕final_result = f[eggs][floors]return final_resultif __name__ == '__main__':print get_min_floor(eggs=2, floors=100)  # 输出结果14print get_min_floor(eggs=2, floors=36)   # 输出结果8print get_min_floor(eggs=2, floors=39)   # 输出结果9print get_min_floor(eggs=3, floors=39)   # 输出结果6

参考:https://blog.csdn.net/Autumn03/article/details/80886814

https://blog.csdn.net/aBen_Dan/article/details/90897527

彻底搞懂-扔鸡蛋问题-方程-动态规划相关推荐

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

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

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

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

  3. 动态规划算法实验报告_搞懂这几点,动态规划算法就是那么简单

    动态规划(Dynamic programming,简称DP),是大家都觉得比较难以掌握的算法.为了应付面试,我们经常会背诵一下斐波那楔数列或者背包问题的源码,其实,只要理解了思想,掌握基本的模型,然后 ...

  4. 一文彻底搞懂递归、备忘录、动态规划

    递归: 递归算法是一类非常常用的算法,它是一种直接或间接调用原算法本身的算法.递归算法最大的特点就是"自己调用自己",对于一些具有递归特性的问题,使用递归算法来解决会更加简单明了, ...

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

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

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

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

  7. 动态规划:高楼扔鸡蛋

    方法一:常规动态规划 1.dp[i][j]数组定义:dp[i][j]表示鸡蛋数量为i,可选楼层数为j的状态下确定F的最少步数,问题所求为dp[K][N] 2.base case:当楼层数为0,步数为0 ...

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

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

  9. LeetCode刷题复盘笔记—一文搞懂0 - 1背包之494. 目标和问题(动态规划系列第九篇)

    今日主要总结一下动态规划0-1背包的一道题目,494. 目标和问题 题目:494. 目标和 Leetcode题目地址 题目描述: 给你一个整数数组 nums 和一个整数 target . 向数组中的每 ...

最新文章

  1. python小游戏开发,使用python实现英语打字游戏
  2. CPU内核配置(一):通用内核配置
  3. NSOprationQueue 与 GCD 的区别与选用
  4. 覆盖你 80 % 网络生活的,竟是这样一家神秘实验室
  5. Redisson--------基础入门
  6. oracle number类型能存空吗_《听雪楼》《白发》成爆款类型剧的效仿者,古装剧真的能回暖吗?...
  7. Yii2.x 互斥锁Mutex-类图
  8. navigationBar设置透明度
  9. Java基础算法--排序
  10. 土壤湿度计检测模块 土壤湿度传感器 机器人智能小车
  11. C语言论坛系统课程设计
  12. 华电研究生学习和工作总结(2021.11.08-2021.11.12)-围城
  13. (RAID原理)JBOD
  14. 基于Open CV的植物图像分类识别项目
  15. 《Think Python》练习 4-1:本章示例代码栈图、停止点偏离思考
  16. c++ C2001 常量中有换行符
  17. 在IDEA中手动创建基于Maven的Servlet项目
  18. 规范的版权Copyright说明怎么写?
  19. Integrity check failed for “antd“ (computed integrity doesn‘t match our records
  20. linux设备驱动归纳总结(十三):1.触摸屏与ADC时钟

热门文章

  1. Java实现 LeetCode 521 最长特殊序列 Ⅰ(出题人:“就是喜欢看你们不敢相信那么简单,又不敢提交的样子。”)
  2. Android程序员该如何进阶?,2021Android面经
  3. 赚商联盟:我是如何实现长期被动引流的,学会这招永不过时
  4. Unity 回合制战斗
  5. 《最优化方法》——数学基础知识线性规划无约束优化算法初步
  6. 中国茶叶分类图(转载)
  7. 国家级示范高等职业院校网址
  8. 【媒体管家】媒体邀约以及媒介投放策略
  9. bellman_ford
  10. oracle常见语句(转载)