再谈大楼扔鸡蛋的问题

这道题是说,100层楼,两个一模一样的鸡蛋,某层之上扔鸡蛋就会碎。问要测试多少次才能找出这层楼来。我曾经在去年初的这篇文章里面讨论过这个问题的解法,因为只想记录一下思路和讨论过程,写得很简略。现在,我想重新整理一下这个问题,再稍稍扩展和挖掘一下。希望可以用尽可能清晰易懂的描述,把这个问题的前后说清楚。

现在只有两个鸡蛋,而算法必须是可行的,就是说要能找出这一层来,所以你得假设你的运气最差,这就意味着,我求解的是在每种扔鸡蛋的策略下都有一个需要扔的次数的最大值,而现在需要求解的是这些最大值中的最小值的问题。如果我只有一枚鸡蛋,这就意味着,我只能从第一层开始老老实实地一层一层往上试,不能越层;而我的运气非常非常差,于是我这样试验的结果就是一直试验到最高一层鸡蛋依然没破,试验的次数就等于楼层数N。

动态规划法求解

现在,我有两枚鸡蛋,第一枚鸡蛋从哪一层楼开始扔就显得至关重要了。如果第一枚鸡蛋碎了,那就回到刚说的只有一枚鸡蛋的问题了。我相信很多人立即映射到脑子里的词是“二分法”,也就是说,第一枚鸡蛋从N/2开始扔,如果碎了,扔的楼层数就是N/2(注意取整);如果没碎,剩下N/2楼层里继续用二分法。可以预计,如果没碎的情况,扔鸡蛋的总次数要小于N/2。也就意味着,还有潜力可挖,如果不用二分法,让扔第一枚鸡蛋的楼层数为x,它小于N/2;同时如果第一枚鸡蛋没碎,接下去的策略,在运气最差的情况下仍然让扔的次数等于x,就最经济了。

最常规的解法是动态规划。可以用动态规划法求解的问题必须满足这样的条件,分割成的子问题是最优解的时候,原问题也是最优解。显然这个问题满足这一点:假设扔的总次数为f(x),在第一次扔碎了的情况下,接下去只能一层一层试验,最多从第1层到第x-1层需要试验x-1次,加上扔第一个鸡蛋那一次,总的次数就是(x-1)+1=x;在第一次没碎的情况下,就相当于一个新的相似子问题:在N-x层中寻找新的扔鸡蛋次数f(N-x),因此总次数就是f(N-x)+1。那么:

f(x)=max(x, f(N-x)+1)

同时,递归求解的出口是:当x=1,f(x)=1。所以,算法大致如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// times[i]表示N取值为i的时候,需要扔多少次
private static int [] times;
 
public static int dropEgg( int N) {
     // 初始化数组
     times = new int [N + 1 ];
     return dp(N);
}
 
private static int dp( int N) {
     // 两层楼或一层楼就没有计算的必要了
     if ( 1 == N)
         return 1 ;
     else if ( 2 == N)
         return 2 ;
 
     for ( int x = 2 ; x < N; x++) {
         int max = maxTimes(N, x);
         if ( 0 == times[N] || times[N] > max)
             times[N] = max;
     }
 
     return times[N];
}
 
// 碎和不碎的次数最大值
private static int maxTimes( int N, int x) {
     int sum = dp(N - x) + 1 ;
     if (x < sum)
         return sum;
     else
         return x;
}

“两个鸡蛋”到“m个鸡蛋”

现在把问题扩展一下,由两个鸡蛋扩展到m个鸡蛋,times数组第一维表示最多可以扔几次,第二维表示扔第几次:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public static int dropEgg( int N, int m) {
     // 初始化数组
     times = new int [m + 1 ][N + 1 ];
     return dp(N, m);
}
 
private static int dp( int N, int m) {
     if ( 1 == m || 1 == N || 2 == N)
         return N;
 
     for ( int time = 2 ; time <= m; time++)
         for ( int x = 2 ; x < N; x++) {
             int max = maxTimes(N, x, time);
             if ( 0 == times[time][N] || times[time][N] > max)
                 times[time][N] = max;
         }
 
     return times[m][N];
}
 
// 碎和不碎的次数最大值
private static int maxTimes( int N, int x, int m) {
     int sum = dp(N - x, m) + 1 ;
     if (x < sum)
         return sum;
     else
         return x;
}

寻找规律

还是回到两个鸡蛋,随着N的值改变,可以发现x呈现这样的变化:

N=1, x=1
N=2, x=2
N=3, x=2
N=4, x=3
N=5, x=3
N=6, x=3
N=7, x=4
N=8, x=4
N=9, x=4
N=10, x=4
N=11, x=5
N=12, x=5
N=13, x=5
N=14, x=5
N=15, x=5
N=16, x=6
N=17, x=6
N=18, x=6
N=19, x=6
N=20, x=6
N=21, x=6
……

换言之,x=1的有1项,x=2的有2项,x=3的有3项……网上最多的问法是当N=100的时候,x是多少,根据这个规律:

(1+x)*x/2>=100

得知x的最小值是14。

下面来证明一下这个猜想:

因为当扔鸡蛋的最小次数为x的时候,第一次从x层开始扔,如果碎了,那么接下去就要扔x-1次;如果没碎,接下去就变成了扔鸡蛋最小次数为x-1的子问题了,此时再扔的楼层数变成了x+(x-1),在这种情况下碎和不碎两种情况下需要再扔的次数是相等的,已经是最经济的扔法了,继续之,可以得到,扔鸡蛋最小次数为x的时候,最高可以检测到的楼层数为:

x+(x-1)+(x-2)+……+1

正好是一个等差数列求和的公式。

这也是为什么,我们可以从网上找到的扔鸡蛋问题,好多都是N等于15、21、28、36这样的数,这正好等于这个等差数列和。

现在把问题稍稍转变一下,把鸡蛋数量的限制去掉,再把求爬楼梯的限制加上,不妨再来求解:

如果鸡蛋数量无限,但是假如说扔一次鸡蛋需要耗费力气a,每爬一层楼(无论向上还是向下)需要耗费力气b,现在用怎样的扔鸡蛋策略,可以让耗费的总力气量最小?

文章系本人原创,转载请保持完整性并注明出自《四火的唠叨》

扔鸡蛋问题(eggs drop) 前两天看书的时候看到这样一个问题,十分有趣,再次分享给大家。jia 阅读详情

相关推荐

算法设计与分析:动态规划法求扔鸡蛋问题 C++

算法设计与分析:动态规划法求扔鸡蛋问题 三种方法:常规动态规划、动态规划加二分查找最优x、动态规划加逆向求解

aw2371的博客 2481

动态规划之《高楼扔鸡蛋》问题详解 && LeetCode 887.鸡蛋掉落

描述 这是LeetCode的第887题。题目如下: 你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑。 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。 你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。 每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X <= N)。 你的目标是确切地知道 F 的值是多少。 无

mbytes的博客 5977

香橙派5使用RK3588S内置NPU加速yolov5推理,实时识别数字达到50fps

香橙派5采用了RK3588S,内置的NPU达到了6Tops的算力,博主这里记录一下自己的踩坑过程,好不容易做出来的不能以后忘记了(手动狗头)。这里博主还在B站上发布了效果视频,大家感兴趣的话可以看一下。其中解决了先验框标注位置不对,或者出现非常多的框的问题

weixin_51651698的博客 2万+

扔鸡蛋问题

假如有100层楼,总共有2个鸡蛋。最低需要多少次才能试探出临界点,比如,在第三层扔下去,不碎;在第四层扔下去,碎了,那第三层和第四层就是临界点。   如果之前没准备过的话,大概第一个想到的就是二分法。 二分法   首先在第50层丢第一个鸡蛋,若鸡蛋碎了,则在第一层开始往上丢鸡蛋,最坏情况是试探49+1次,为什么要从第一层开始尝试呢,因为只有2个鸡蛋;若鸡蛋没碎,则在75层...

卖克的专栏 1万+

485芯片AB波形正负半周的问题探讨

      本人做的一个产品,产品的其中一个接口是RS485的,我们使用的芯片是MAX13487E。MCU是STM32F103,MCU的USART通过光耦隔离后,接到MAX13487E。因为STM32F103的VCC是3.3V的,MAX13487E的VCC是5V。      部分原理图如下,上述部分电路参考了官方的参考设计,现在测试的AB波形时候发现如下问题。1.把R10和R16改为1k,示波器C...

qq_26308521的博客 1万+

基于PID的定速巡航控制系统设计【MATLAB源码+Word文档】

本文详细介绍了定速巡航控制是一种车辆驾驶辅助系统,它能让驾驶者在高速或长途驾驶时,设定一个固定的车速,然后车辆会自动维持这个速度行驶,无需驾驶者持续踩油门。这大大减轻了驾驶者的疲劳,同时也提高了行驶的安全性。PID定速巡航控制系统是一种利用比例(Proportional)、积分(Integral)和微分(Derivative)控制算法来实现车辆定速巡航的先进系统。这种系统能够根据设定的速度,自动调整油门开度或制动力度,使车辆保持恒定的速度行驶。这种控制系统具有响应速度快、控制精度高、稳定性好等优点。

weixin_761237174的博客 1670

Leetcode 887. 鸡蛋掉落 DP

你将获得K个鸡蛋,并可以使用一栋从1到N共有N层楼的建筑。 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。 你知道存在楼层F,满足0 &lt;= F &lt;= N任何从高于F的楼层落下的鸡蛋都会碎,从F楼层或比它低的楼层落下的鸡蛋都不会破。 每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层X扔下(满足1 &lt;= ...

Evildoer_llc的博客 750

ST电机库实战:从状态机到稳健启动流程的深度解析

本文深度解析了ST电机库中状态机的核心作用与稳健启动流程。状态机作为电机控制的“交通指挥官”,通过IDLE、CHARGE_BOOT_CAP、ALIGNMENT等一系列状态的严格跳转,确保了永磁同步电机(PMSM)和直流无刷电机(BLDC)的安全启动与可靠运行,是避免硬件损坏和实现平稳控制的关键。

weixin_29161785的博客 226

大楼扔鸡蛋的问题 动态规划法

这道题是说,100层楼,两个一模一样的鸡蛋,某层之上扔鸡蛋就会碎。问要测试多少次才能找出这层楼来。我曾经在去年初的这篇文章里面讨论过这个问题的解法,因为只想记录一下思路和讨论过程,写得很简略。现在,我想重新整理一下这个问题,再稍稍扩展和挖掘一下。希望可以用尽可能清晰易懂的描述,把这个问题的前后说清楚。 现在只有两个鸡蛋,而算法必须是可行的,就是说要能找出这一层来,所以你得假设你的运气最差,这

Cloud-Datacenter-Renewable Energy-Big Data-Model 1526

【DRAM存储器六十二】DDR5介绍--引脚和基本功能简介

详述DDR5与DDR4的引脚区别和DDR5基本功能

highman110的博客 524

ABAP Channels 实战:在 ABAP 7.40 中用 WebSocket 打造实时双向通信

本文详细介绍了SAP ABAP 7.40引入的ABAP Channels通信框架,包含AMC(ABAP Messaging Channels)和APC(ABAP Push Channels)两部分。AMC作为应用服务器内部的消息总线,支持发布/订阅模式,可实现跨会话实时通信;APC基于WebSocket协议,用于浏览器等客户端与ABAP服务器的双向实时交互。文章通过一个乒乓球游戏案例展示了ABAP Channels的实时协作能力,并详细解析了AMC的配置方法、消息发送与接收的代码实现,帮助开发者理解如何利用

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 221

清晰解题:扔鸡蛋问题

一幢 100 层的大楼,给你两枚鸡蛋。假设,在第 n 层扔下鸡蛋,鸡蛋不碎,那么从第 n-1 层扔鸡蛋,鸡蛋也不会碎。两个鸡蛋一模一样,不碎的话可以扔无数次。目标是利用这两个鸡蛋找出临界楼层 t , 使得鸡蛋从 t 层扔下不会碎, 从 t+1 层扔下会碎。 现要求回答, 最少需要多少次尝试, 才能保证在最坏的情况下,找到楼层 t , 且需要给出尝试的策略。 明确问题 题目要求是考虑 在...

萧萧的专栏 8342

YOLOv11改进 | 模型知识蒸馏篇 | 利用模型蒸馏改进YOLOv11进行无损涨点 | CWDLoss(在线蒸馏 + 离线蒸馏)

这篇文章给大家带来最新改进的是模型的蒸馏利用教师模型指导学生模型从而进行模型的涨点,本文的内容不仅可以用于论文中,在目前的绝大多数的工作中模型蒸馏是一项非常重要的技术,所以大家可以仔细学习一下本文的内容,本文从YOLOv11的项目文件为例,进行详细的修改教程,文章内包括完整的修改教程,针对小白我出了视频修改教程,如果你还不会我提供了修改后的文件大家直接运行即可,所以说不用担心不会适用!模型蒸馏真正的无损涨点,蒸馏你只看这一篇文章就足够了!欢迎大家订阅我的专栏一起学习YOLO!

Snu77的博客 3309

大楼扔鸡蛋问题 dp poj 3783

题意分析: 经典题,小白书上的一道例题,4+2出了这道原题,我愣是以为是数学题,最后也没做出来。题意是这样的,给你N个鸡蛋(硬度一样),让你测鸡蛋的硬度,测量的方法就是从某栋M层的楼的某一层X上把鸡蛋扔下来,如果鸡蛋碎了,代表他的强度小于X;如果没碎,则强度大于等于X。我们要做的就是不断的从楼上把鸡蛋扔下来,直到找到某一层楼X,从这一层楼扔下来鸡蛋不碎掉,从X+1层扔下来鸡蛋碎掉,那么鸡蛋的强度就

liuyanfeier的专栏 1958

【PINN高级教程】 第1讲:函数空间与逼近理论

结论:在解决偏微分方程(PDE)时,解往往属于某个 Sobolev 空间 HsHs,其正则性受限于 PDE 的系数与边界条件;而 PINN 在训练过程中实际上是在逼近 Barron 空间中的函数。由于 Barron 空间允许高频信息的压缩,PINN 可以在参数规模较小的情况下捕捉到 PDE 解所需的细节,但其正则性保证仍然比 Sobolev 更弱。因此,在设计 PINN 时,需要通过正则化或网络结构(如残差连接、归一化层)来“逼近”Sobolev 正则性。

u012133341的博客 237

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

总结 扔鸡蛋问题——1

前言 最近我在知乎上看到了一个扔鸡蛋的问题[1],问题描述如下。在网上学习后,将相关知识整理如下。 正文 问题 有一个 n 层的建筑。如果一个鸡蛋从第 k 层及以上落下,它会碎掉。如果从低于这一层的任意层落下,都不会碎。 有 2 个鸡蛋,用最坏的情况下实验次数最少的方法去找到k, 返回最坏情况下所需的实验次数。 拓展:若有m个鸡蛋,返回最坏情况下所需的实验次数。 测试用例: m = 2, n=10...

雒阳的博客 875

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

【面试】扔鸡蛋问题

你有两个相同的鸡蛋,和一栋100层的大楼。你需要找到一个临界楼层,从这个楼层或更高楼层扔下鸡蛋会破裂,而低于这个楼层扔下鸡蛋则不会破裂。你的目标是在最坏情况下,用最少的试验次数确定这个临界楼层。试验,才能确定临界楼层。这个方法是最优的,因为它最大化了利用两次鸡蛋破裂的机会,减少了每次试验后的剩余楼层数。这个问题的核心在于如何在两次鸡蛋破裂的机会内,找到最小的试验次数。通过使用分段跳跃的方法,最坏情况下最少需要。

Lewiz_124的博客 485

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

ACM--楼层扔鸡蛋问题

鸡蛋 Time Limit:1000MS  Memory Limit:65536K Description Gardon有一些鸡蛋,他现在想知道这些鸡蛋的硬度。Gardon的家住在一座很高很高的大楼里,他现在要在这座大楼上测试鸡蛋的硬度。每个鸡蛋的硬度相同,鸡蛋的硬度定义为:如果鸡蛋从第m层上掉下来没有破裂,而从第m+1层上掉下来就破裂了,那么这个鸡蛋的硬度就是m。某个鸡蛋如果在实验中破裂

1203

算法第四版扔鸡蛋问题

算法第四版1.4.25、1.4.26扔鸡蛋问题

qwas12345qwas的博客 1604

算法--Google的楼层扔鸡蛋问题

算法-Google的楼层扔鸡蛋问题 扔鸡蛋问题其实在网上已经在网上有很多答案了,有的使用迭代法,有的根据递归和的方法.对于可接受的方法来说递归和的方法无疑是可以做的有效的计算的方法,迭代法随便给个值以后简直可以认为无解.但是大部分人给出递归和的同时往往缺少一个严谨的证明,从而导致整个方法所依赖的理论是不成立的.迭代法就不多说了,网上的文章一搜一大把.今天着重说下通过递归和方法的证明. 先看题目 一幢 100 层的大楼,给你两个鸡蛋. 如果在第 n 层扔下鸡蛋,鸡蛋不碎,那么从前 n-1 层扔鸡蛋都不碎. 这

a_lzq的博客 466

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

1.问题描述两个软硬程度一样的鸡蛋,它们有可能都在一楼就摔碎,也可能从一百层楼摔下来没事。有座100层的建筑,用这两个鸡蛋确定哪一层是鸡蛋可以安全落下的最高位置,可以摔碎两个鸡蛋,求给出一个最佳策略,测出鸡蛋恰好不会碎的楼层,最佳策略满足的条件就是在最坏情况下所扔的次数比其它任意策略的最坏情况下所扔的次数要少。并求最佳策略在最坏情况下所仍的次数。2.问题剖析使用一个鸡蛋我们别无选择,只有一种方案就是...

Doublelv 的博客专栏。 6947

高楼扔鸡蛋(面试题)

高楼扔鸡蛋问题 这个问题很有名了 早几年之前面试的时候都遇到过,但是当时也确实没搞清楚怎么做,后来也没管了。今天网上偶然碰到,打算趁这个机会彻底搞清楚,就写一篇博文吧。网上很多资料,但我感觉都不太易懂,每一步的推导是为什么。所以我这里只想写一种比较简单、比较完整的推演流程。 题目描述: (挑了一个比较严谨的描述。问题描述严谨很重要,不然会影响解题思路) 一幢 100 层的大楼,给你两个鸡...

JYMiracle的博客 504

扔鸡蛋

试想一下,虽然第一次就缩减一半的查找量很有吸引力,仿佛很爽的样子,但是要明白,蛋碎了接下来还是一个漫长的寻找过程,那么,有木有办法可以让第一枚鸡蛋和第二枚鸡蛋的尝试次数尽可能均衡呢?(可以理解成在第一枚蛋查找的范围尽可能的大和第二枚蛋查找的范围尽可能的小之间的一个平衡。)可能会有人说这俩事是矛盾的,确实,就是这样,但是我们可以在两者之间找到一个平衡点。 接下来,是关于平衡点的探索: 首先,很简单的...

ailinyingai的博客 190

关于100层楼,扔两个鸡蛋,求摔碎鸡蛋的临界层的问题

题目描述:         两个软硬程度一样但未知的鸡蛋,它们有可能都在一楼就摔碎,也可能从一百层楼摔下来没事。有座100层的建筑,要你用这两个鸡蛋确定哪一层是鸡蛋可以安全落下的最高位置。可以摔碎两个鸡蛋。   网上有人说可以写动态规划方程来解决,我也没看。不过依我之见,这个问题通过简单的证明就可以得出结论。我们可以直接对n层建筑来分析。 如果我们只有一个鸡蛋,那么只能从最底层,一层一层的

woodbean的专栏 5206

Google面试题-高楼扔鸡蛋问题

Google面试题-高楼扔鸡蛋问题 简单详尽的理解思路

lonelyrains的专栏 1万+
上一篇: 有趣还是无趣?
下一篇: JavaScript使用for循环时出现的问题
RayChase
博客等级 码龄20年 71粉丝 87原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值