C++,python,热爱算法和机器学习
全部博文(1214)
分类: Python/Ruby
2012-05-11 12:38:32
100层楼2个鸡蛋,如何得知鸡蛋能承受几层的撞击。没太明白题意,google之。
1. 你有2个一摸一样的鸡蛋(所有性质相同)。
2. 有一幢100层的楼。注意即使是一楼和地面也有距离的。
3. 鸡蛋可能很硬也可能很软, 意思是有可能从一楼扔下来就碎了, 也有可能从100楼扔下来还不碎。
4. 你必须,是*必须*搞清楚最高从几楼扔下来鸡蛋是不会碎的。
5. 此过程中你被允许打破这2个鸡蛋。
6. 只准用从楼上扔鸡蛋的方式测试, 不能有任何别的辅助工具和手段。
微阅堂和一个OI博客 都有提到过,曾经也和同学讨论过,这次看到有点蒙,想了一会想出来了。
不能用二分法,因为如果在50层碎了,下面的策略就是一层一层的试验了。一定有一个最低层L,碎了就从第一层测试到L-1层,没碎就往上走。
测试一次如果没碎,那么往上走的层数需要比上一次上楼的层数减1,上到100层时上楼的次数就应该等于L,这样无论在哪里第一个蛋碎了,两个蛋测试总次数都是相同的。
于是: L + (L-1) + ... + (L-L) = 100 => L*L - [1+2+...+(L-1)] = 100
解得: L = 13.x
最后验证:
14+13+12+11+10+9+8+7+6+5+4 = 99 用了11次.
13+12+11+10+9+8+7+6+5+4+3+2+1=91 不到100
结果是14。连程序都省了。
如果微阅堂的300层楼,3个鸡蛋呢?这个要用到动态规划(DP)。
有n层楼k个鸡蛋,则在第r层楼扔下鸡蛋只有破和不破两种情况,如果破了则问题转化为测定n-1层楼,k-1个鸡蛋所需的最小次数+1;如果不破则转化为测定n-r层楼,k个鸡蛋所需的最小次数。
公式表示:
F(n, k) = min ( max(F(n-r, k) , F(r-1, k-1)) + 1), r = 1, 2, …, n;
F(n, 1) = n; F(0, n) = 0
递归的程序:
点击(此处)折叠或打开
问题:
做了cache,貌似是吧时间复杂度从指数降到O(nk)级别了。递归的时间复杂度总是想不清楚。
大数据量时python有递归层数限制,无法计算,可以转换成C代码。但毕竟系统栈有限(貌似2M),用递归不是最好的方法。谁有更好的方法吗?