这道题是说,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,现在用怎样的扔鸡蛋策略,可以让耗费的总力气量最小?
文章系本人原创,转载请保持完整性并注明出自《四火的唠叨》
相关推荐
对于yb和515两个版本,它们可能代表了游戏的不同更新或改进版本,例如可能包含新的功能、修复了已知问题或者优化了游戏性能。玩家可以尝试这两个版本,看看哪个更适合自己。 总的来说,Java版摩天大楼是一款基于...
智慧办公大楼信息化建设和应用综合解决方案 智慧办公大楼信息化建设和应用综合解决方案是指在办公大楼建设和应用中,通过信息化手段和智能化技术,实现办公大楼的高效、安全、环保和智能化管理。该解决方案旨在提高...
当前的智能化管理存在许多痛点,包括高端商业大楼客户多为精英群体、高端商务需求对于智能化管理提升工作效率和提升用户体验需求十分迫切等问题。该解决方案通过智能化管理平台,实时智能调控、门禁电梯类设备等智能...
1. **建筑设计** - 中央电视台总部大楼是由荷兰建筑师雷姆·库哈斯(Rem Koolhaas)及其所在的荷兰大都会建筑事务所(OMA)设计的,展现了一种独特的后现代主义风格。大楼的两座塔楼以6度的内倾角度相互连接,形成...
某大楼综合布线方案某大楼综合布线方案某大楼综合布线方案
### 大楼通信综合布线系统:核心知识点详解 #### 1. 概述与标准背景 大楼通信综合布线系统是指在建筑物内部构建的一种高度集成化的通信基础设施,旨在为语音、数据、图像等信息传输提供高效、稳定、灵活的物理介质...
【某海运公司办公大楼工程QC成果报告】 本报告聚焦于运用质量管理(QC)方法来控制某海运公司的办公大楼工程的合同工期。这份成果报告由浙江昌鼎建设有限公司的“舟山浩舟海运公司办公大楼工程QC小组”发表,旨在...
随着信息技术的发展,传统的办公大楼面临系统繁复、建设和维护困难、功能浪费等问题。同时,用户对便捷、高效和个性化的体验需求日益增长。智慧办公大楼旨在解决这些问题,通过大数据分析提供定制化服务,提高管理...
本文作者盛国武,来自浙江宏纪工程安装有限公司,探讨了智能大楼消防应急照明系统供电方式和消防联动控制的常见问题。 首先,应急照明系统的供电方式选择至关重要。按照《消防应急灯具》GB17945-2000标准,消防应急...
办公大楼综合布线系统图纸.pdf 本资源是一个关于办公大楼综合布线系统图纸的PDF文件,该文件中包含了综合布线系统图设计与平面布置的相关信息。 知识点1: 综合布线系统 综合布线系统是一种结合了计算机网络、电话...
智能办公大楼详细设计方案,用作甲方沟通模板或投标设计文件
### 综合大楼布线拓扑图案例分析 #### 一、引言 在现代建筑中,布线系统是确保信息传输稳定性和高效性的关键基础设施之一。合理的布线设计不仅能够满足当前的需求,还能为未来的技术升级预留空间。本文将通过对一...
《摩天大楼》是一款深受玩家喜爱的休闲类游戏,它将建筑、管理和模拟元素融为一体,为玩家提供了一次独特的建设体验。在这个游戏中,玩家扮演的角色是城市规划者和建筑师,负责设计、建造并运营一座座矗立云端的摩天...
BIM在腾讯北京总部大楼项目中的应用
智慧大楼弱电智能化规划设计方案是现代建筑领域的重要组成部分,它涉及到多个子系统,旨在提高楼宇的运营效率、安全性和用户体验。以下将详细阐述这些子系统的功能、设计原则以及其在智慧楼宇中的应用。 1. 系统...
NOKIA 手机上很有趣的盖大楼的游戏. 没有的可以下载玩玩!
计算机网络系统以目前国际流行的TCP/IP为基础,采用OSI体系结构,遵循国际标准,整个计算机网络系统采用星型拓扑结构。
智慧大楼IBMS可视化大数据应用