最高的解决方案实际上是
O(D*B)(使用问题的术语),但是作者注意到,对于大多数人来说
D,
B答案将大于
2^32并且
-1可以返回。
所以,他介绍
maxn等于1100 -最大
D和
F为它是有道理的计数。
因为
D, B = 10000他马上返回-1。对于
D, B = 100递归公式,使用下面的公式。仅对某些“角值”(例如
D = 10000, B =2)使用直接公式。(有关“直接公式”的详细信息,请参阅他的评论)
为此
D, B < maxn,作者在评论中提供了公式:
f(d,b) = f(d-1,b)+f(d-1,b-1)+1。
f这里的函数返回最多可以使用“
d尝试”和“
b鸡蛋”来确定“断点”的楼层数。
公式本身应该是不言而喻的:无论我们在哪个楼层投出第一枚鸡蛋,都有两个结果。它可能会破裂,然后我们可以检查
f(d-1,b-1)下面的楼层。或者它可以“生存”,那么我们可以检查
f(d-1,b)上面的楼层。以当前楼层为单位,这使其
f(d-1,b)+f(d-1,b-1)+1总数为零。
现在,可以轻松地将其编码为DP(动态编程)。如果您留下无穷大(
2^32)签出,它将变得非常干净。
for (int i = 1; i < maxn; ++i) { for (int j = 1; j < maxn; ++j) { f[i][j] = f[i - 1][j - 1] + f[i - 1][j] + 1; } }当我们有
f[D][B]存储这些结果的数组时,找到
D'和
B'是二进制搜索。(因为函数
f由
d和都单调增长
b)
PS尽管我在回答“猫”问题时确实说过,有一个更快的解决方案,但实际上比我想的要 酷 :)多亏了您和 sclo (作者)!



