热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

数学逻辑_丢鸡蛋_谷歌面试题

问题:有一栋楼,共100层。定义:鸡蛋在第n层楼扔下,不会碎,第n+1层扔下,会碎,那么第n层就叫临界楼层你手中有两个鸡蛋(默认理想状态:两个鸡蛋完全相同),如何优化尝试策略,使得使用最少
问题:
有一栋楼,共100层。
定义:鸡蛋在第n层楼扔下,不会碎,第n+1层扔下,会碎,那么第n层就叫临界楼层
你手中有两个鸡蛋(默认理想状态:两个鸡蛋完全相同),如何优化尝试策略,使得使用最少次数,测出临界楼层
即,使用此策略,最差也可以在多少次以内测出临界楼层

(ps:假定鸡蛋一定会在某层楼下落后碎掉)

解题思路:

注意:手中只有俩鸡蛋,必须要保证全碎之前测试出临界楼层

1. 为了不让鸡蛋碎掉,我们从一楼开始测试,这样只需要一个鸡蛋,当到达临界楼层的上一层n+1时,我们可以得出,n层是临界楼层,这是最原始的方法,遍历。

这种策略最糟糕的情况会是测试到100楼鸡蛋才会碎,测试次数是100次,临界楼层是99楼。最好的情况是测试到2楼鸡蛋就碎了,测试次数是2次,临界楼层是1层。

2. 我们手中有俩鸡蛋,为了充分利用条件,我们可以利用第一个鸡蛋来缩小范围。

我们可以先跑到50楼去扔,没碎的话,我们再去75楼去扔···直到第一个鸡蛋碎掉。

如果我们从50楼扔,没碎,说明50楼以下是安全的,50楼以上还有50楼,那我们再去上面的50楼的一半——75楼去扔,在75楼碎了,说明临界楼层在50层~74层之间,我们就利用第二个鸡蛋,遍历51层到74层。这是运用二分法。

这种策略最糟糕的情况会是50层鸡蛋就碎了,49层是临界楼层,测试次数是1+49次,临界楼层是99楼。最好的情况是1楼是临界楼层,测试次数是1+2次。

3. 还有没有更好的办法呢?我们手中有两个鸡蛋,尝试使每个鸡蛋的测试任务大致相当,即给100开个平方根,第一个鸡蛋只测试整十楼层,第二个鸡蛋测试两个整十楼层之间的楼层。我们可以先测10楼,20楼,30楼···,直到第一个鸡蛋碎掉。

如果我们测到30楼,第一个鸡蛋碎了,那我们就用第二个鸡蛋遍历测试21~29楼。

这种策略最糟糕的情况会是99层是临界楼层,测试次数是10+9次。最好的情况是1楼是临界楼层,测试次数是1+2次。

4. 这个时候我们产生了疑问,第三种方法是最好的策略吗?我们怎么验证呢?

验证这种事情,我们肯定要借助数学工具了

 

首先,我们我们假定存在一种最优策略,最多n次测试就能找到临界楼层

那么,最糟糕的状况会是哪一种呢?

从上面的分析可以看出,测试次数分为两部分

第一颗鸡蛋的测试次数x,用来缩小范围

第二颗鸡蛋用来在小范围内查找临界楼层y

x+y=n

那么当测试次数固定为n时,每当x增加1,y则减少1

即,每当第一颗鸡蛋测试一次,那么所留给第二颗鸡蛋探查的范围就应该减少1

此处内容用于帮助各位理解:

如果n=10,那么第一次探查了20楼,使用了一次机会,如果碎了,确定的范围是1~19,那么,第二颗鸡蛋需要使用10-1次机会去探查19层,在最糟糕的情形下显然无法完成。

显然当n=10时,第一次探查为10楼显然更合适,确定下来的范围是1~9,第二颗鸡蛋使用10-1次探查9层楼,最糟糕的情形下也能满足。

如果探查10楼后鸡蛋没碎,而在第二次探查时碎了呢?我们第二次探查应该把范围再缩小1,如果第一个鸡蛋多探查一次,那么留给第二颗鸡蛋的探查机会就少一次,我们要保证在最糟糕的情形下也能探查到,所以留给第二颗鸡蛋的探查范围应该与其探查机会相等。即第一颗鸡蛋的第二次机会应该探查第19层,确定下来的范围需要探查的范围是11~18,第二颗鸡蛋的剩余探查次数刚好为10-2,匹配成功

·····

根据以上分析,我们可以发现,每一次的探查范围都减一,即n-1,n-2,n-3,....2,1,0

最后我们的探查范围会缩小到0

那么我们把这些探查范围加起来,再加上n就是我们的探查总范围

 

 即n+(n-1)+(n-2)+······+3+2+1+0=100

解的n刚好为正整数14,即使用此策略最多探查14次即可在100楼中找到临界楼层

另外,当探查总范围发生改变时,解的n可能为小数,显然,探查次数只能为整数且n越小探查总范围越小,

n应向上取整 


另外一种理解方式:

对这个问题,原始问题:100层楼,最少需要几次测试,才能得到摔碎鸡蛋的楼层 ,直接考虑不容易考虑,但是,如果将这个问题进行一种等价的转换,这个问题将会变得非常容易解答。

个人认为,这个转换是解决这个问题的核心,这个转换是:

转换问题两个鸡蛋,进行k次测试,最多可以测试几层楼

如果大家能想到将“原始问题”变为“转换问题”,这个问题个人认为已经解决一半了,转换后,这个问题豁然开朗,思路全开。

现在我们以“转换问题”为模板进行考虑,有两个鸡蛋,第一个鸡蛋如果破碎,第二个鸡蛋就必须只能一层一层的测试了,而且,我们要求进行k次测试就将摔碎鸡蛋的楼层必须找到.

 

考虑第一次测试。第一次测试的时候,第一个鸡蛋不能放置的楼层太高了,否则,如果第一个鸡蛋破碎,第二个鸡蛋可能不能在k次测试后得到结果。但是也不能放置的矮了,因为如果放置的矮了,第一个鸡蛋破碎了还好说,如果没破,我们浪费了一次测试机会,也不能说是完全浪费了,不过至少是让效用没有最大化。所以,第一次测试的时候必须让第一个鸡蛋放置的不高不矮。

 

不高不矮是多高?高到如果第一个鸡蛋破碎后第二个鸡蛋刚好能完成k次测试得到结果这个目标。由此可知,第一次测试所在的楼层高度为k,如果第一次测试第一枚鸡蛋破碎,则剩下k-1层楼,一层一层的试,k次一定能完成目标。

如果第一次测试,第一枚鸡蛋没有破碎,则我们现在只有k-1次测试机会了,而且直到了k楼及其以下都是安全的了。我们消耗了一次测试机会,但是一次就测试了k层楼。

然后只有k-1次机会了,第二次测试,我们可以在k层的基础上再增加k-1层了,注意,这个时候由于我们只有k-1次机会,所以这次只能再增加k-1层,以保证测试的时候第一枚鸡蛋破碎的情况下仍然能完成任务。

于是,重复上述过程,直到最后一次机会,我们总共测试的楼层数为:

这里的k相当于(k-1) + 1,对于一个鸡蛋,k-1次机会最多可以测试k-1层楼,再以此类推

然后,再回到“原始问题”,100层楼,如果需要k次测试才能测试完成,则必须有:

则可以得到,k≥14

要是求N层楼把这里的100换成N就行了,k仍然需要向上取整

 

然后,这个问题这个时候还可以扩展了,如果我们有三个鸡蛋,有k次机会,我们最大可以测试多少层楼?

思路同前面一样,第一次测试,不能太高也能太矮,必须恰到好处,也就是第一枚鸡蛋如果破碎,剩余k-1次机会能将剩余楼层给测试完。

由上面结论,k-1次机会最多可以测试k(k-1)/2层楼,所以第一次在k(k-1)/2+1层楼,第一次如果第一枚鸡蛋不碎,第二次在此基础上增加(k-1)(k-2)/2+1层楼,于是,三个鸡蛋k次机会总共测试楼层数为:

至于四个鸡蛋,五个鸡蛋,以至于M个鸡蛋,可以以此类推,方法同上。此处原理讲通,就不推导了


 

附:

动态规划解法

定义状态f[n][m]:N个鸡蛋从M层摔找出最少的尝试次数,测试出鸡蛋不会摔碎的临界点

状态转移方程:f[n][m] = 1+max( f[n-1][k-1],f[n][m-k] ) (1

解释:
1. 当手里有n个的时候,鸡蛋从k层往下摔,如果破了,那么手里只有n-1鸡蛋了,那么就需要测试f[n-1][k-1]楼层 
2.没破,那么手里还有n个鸡蛋,那么需要测试k+1~m这些楼层

此时我想问下,当手里有2个鸡蛋测试1~m-k层和手里有2个鸡蛋测试k+1~m有什么区别? 
有人说有,因为楼层越高越容易碎,那其实是你个人的想法罢了。其实并没有区别,所以公式可以写为f[n][m-k]


 

 

参考自:

https://blog.csdn.net/qq_42403562/article/details/80949764

http://blog.sina.com.cn/s/blog_6c813dbd0101bh98.html

https://mp.weixin.qq.com/s__biz=MzIxMjE5MTE1Nw==&mid=2653194375&idx=1&sn=26cfa25b698eb2f6a04dceb151cbc8df&chksm=8c99fa5dbbee734b434187ac7964103e9e098b2d1c47f27f883934b155e89be2c5dee085db82&scene=21#wechat_redirect(这个超级可爱)

 


推荐阅读
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 最近任务读书数据分析移动端入门【React文章列表】入门学习-文本渲染http:www.cnblogs.comhuxiaoyun90p4783663.htmlJSX语法http:w ... [详细]
  • 智商狂飙,问了ChatGPT几个数据库问题后,我的眼镜掉了
    原标题:智商狂飙,问了ChatGPT几个数据库问题后,我的眼镜掉了最近,ChatGPT火爆全网,介绍其产品、公司、作者、技术和应用等方面信息,占据着整个互联网,似乎不谈GPT好像 ... [详细]
  • 作者|COLINHARPER译者|火火酱责编|徐威龙封图|CSDN下载于视觉中国“通过使用微支付通道网络,借助当今现代台式计算机上可用的计算能力,比特币 ... [详细]
  • 本文比较了eBPF和WebAssembly作为云原生VM的特点和应用领域。eBPF作为运行在Linux内核中的轻量级代码执行沙箱,适用于网络或安全相关的任务;而WebAssembly作为图灵完备的语言,在商业应用中具有优势。同时,介绍了WebAssembly在Linux内核中运行的尝试以及基于LLVM的云原生WebAssembly编译器WasmEdge Runtime的案例,展示了WebAssembly作为原生应用程序的潜力。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • Final关键字的含义及用法详解
    本文详细介绍了Java中final关键字的含义和用法。final关键字可以修饰非抽象类、非抽象类成员方法和变量。final类不能被继承,final类中的方法默认是final的。final方法不能被子类的方法覆盖,但可以被继承。final成员变量表示常量,只能被赋值一次,赋值后值不再改变。文章还讨论了final类和final方法的应用场景,以及使用final方法的两个原因:锁定方法防止修改和提高执行效率。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 本文介绍了Linux Shell中括号和整数扩展的使用方法,包括命令组、命令替换、初始化数组以及算术表达式和逻辑判断的相关内容。括号中的命令将会在新开的子shell中顺序执行,括号中的变量不能被脚本余下的部分使用。命令替换可以用于将命令的标准输出作为另一个命令的输入。括号中的运算符和表达式符合C语言运算规则,可以用在整数扩展中进行算术计算和逻辑判断。 ... [详细]
  • https:www.bilibili.comvideoav43996494?p61补充说明(修正前面代码存在问题):#先验框筛选defchoose_anchor_boxes(sel ... [详细]
author-avatar
eggplant
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有