丢鸡蛋问题

admin2025-11-22 16:34:167700

Google面试题,蓝桥杯题目

你拿着N个一模一样的鸡蛋站在M层的大楼上。鸡蛋或许很结实,到从楼顶掉下也不会摔破,或许很易碎,在一楼摔下就破碎。

最少试验多少次可以100%找出(鸡蛋不会被摔碎的最高楼层,全部都会摔碎也能找出,为0)?

N可以是1-100。M可能是1-500。

样例

输入(N,M):

1 100

输出

100

解法:

对于只有1颗鸡蛋的情况,我们别无选择,只能从1楼开始,逐层向上测试,直到第i层鸡蛋摔碎为止,

对于2颗,选择折半?在50层丢,碎了最坏情况就是50次(不会被摔碎的最高楼层为49),没碎,继续折半

折半是个好办法,但是不是最优,问题出现在折半的碎和不碎差距很大

最优解法:让碎和不碎都是尝试一样的次数

采用dp,自下往上 或者 递归+备忘录

由于时间问题,这里采用python实现递归+备忘录,请读者自行解决c语言dp

import traceback

def f(eggCount,layer):

try:

if array[eggCount][layer] != -1:

return array[eggCount][layer]

if eggCount == 1:

array[eggCount][layer] = layer

return layer

min = layer

for i in range(1,layer+1):

#存储碎和没碎的临时答案

sui_lin = f(eggCount - 1, i - 1) +1

busui_lin = f(eggCount, layer-i) +1

# print("eggCount:"+str(eggCount)+",layer:"+str(layer))

# print("i:"+str(i))

# print("sui_lin:"+str(sui_lin))

# print("busui_lin:" + str(busui_lin))

if busui_lin >= sui_lin: # 不管碎还是不碎,每次选择更差情况,全局就是最差情况

min = busui_lin if busui_lin < min else min

else:

min = sui_lin if sui_lin < min else min

# 存储最优答案

array[eggCount][layer] = min

# print("eggCount:" + str(eggCount) + ",layer:" + str(layer))

# print(min)

return min

except:

print(eggCount)

print(layer)

traceback.print_exc()

exit()

buildingMinLayer=1

buildingMaxLayer=100

eggNum=2

# currentBestCount = buildingMaxLayer

array=[[]] #第0层没有数据

for i in range(eggNum):

array.append([-1 for x in range(buildingMinLayer-1,buildingMaxLayer+1)]) # 第0个没有数据

# for i in array:

# print(i)

result = f(eggNum,buildingMaxLayer)

print(result)

# 缺点,当数据量大:maximum recursion depth exceeded in comparison