前两天翻译Python文档翻译到手软。今天不想翻译了,上网闲逛,在http://programming.reddit.com/ 上看到一道有趣的题目,据说是清华东门某家公司的面试题。原文地址http://classic-puzzles.blogspot.com/2006/12/google-interview-puzzle-2-egg-problem.html
两个软硬程度一样但未知的鸡蛋,它们有可能都在一楼就摔碎,也可能从一百层楼摔下来没事。有座100层的建筑,要你用这两个鸡蛋确定哪一层是鸡蛋可以安全落下的最高位置。可以摔碎两个鸡蛋。
下面是偶的思路。
这是一个很典型的动态规划问题。用确定minNum[n]表示鸡蛋从高n层的楼摔下不碎需要的最小次数。则有
转移方程:
minNum[n ] = min(1 + max(i – 1, minNum[n-1])) for 1<=i <= n
边界条件:
minNum[0] = 0; minNum[1] = 1
假设i是第一次扔鸡蛋的楼层,如果破了,则为了确定下面楼层中的安全位置,需要从第一层挨着试,需要i-1次,不碎的话上面还有n-i层,还剩两个鸡蛋,需要minNum[n-i]次。
Python代码如下:
#The Standard Problem in simple writing goes like this:
#
#
#* You are given 2 eggs.
#* You have access to a 100-storey building.
#* Eggs can be very hard or very fragile means it may break if dropped from the first floor or may not even break if dropped from 100 th floor.Both eggs are identical.
#* You need to figure out the highest floor of a 100-storey building an egg can be dropped without breaking.
#* Now the question is how many drops you need to make. You are allowed to break 2 eggs in the process
N = 100
# the element of result is a tuple
# first elem of the tuple is the mininum number needed
# second elem of the tuple is the firs position to throw the egg
results = [(0, 0), (1, 1)]
for i in range(2, N+1):
minNum, minPos = N + 1, -1
for j in range(1, i + 1):
temp = 1 + max(j - 1, results[i - j][0])
if temp < minNum:
minNum, minPos = temp, j
results.append((minNum, minPos))
for result in results:
print result
偶的思路适合计算机蛮干。原作者的思路更简单。拿具体的数字作例子,假设100层楼扔16次可以搞定,那么第一次可以且最矮必须从16层扔。碎了好说,从第一层开始试,不碎的话还有15次机会,同理最矮可以从31层开始扔
每次可以扔的最矮楼层如下
16
16 + 15 = 31
31 + 14 = 45
45 + 13 = 58
58 + 12 = 70
70 + 11 = 81
81 + 10 = 91
91 + 9 = 100
超额完成目标。假设需要扔n次,则有
n + (n-1) + (n-2) + … + 1 >= 100
n (n +1) >= 200
min(n) = 14
好好的鸡蛋摔碎了多可惜,Google有钱也不能这样烧啊。打碎了搅拌均匀,加少许凉开水。一定要是凉开水,蒸了才不会有气泡,不然蒸出来和蜂窝似的,又难看又难吃。放到电饭锅蒸格上和米饭一起热。跳闸了再洒少许香葱末和香油,盖上盖子捂两分钟,美味的鸡蛋羹就出锅了。