鸡蛋掉落问题解析

问题简述:有 K 个鸡蛋, N层楼,临界点F楼层扔鸡蛋碎, 最少扔step次能确定临界点F。
求step

Talk is cheap, show u the code:

class Solution:
    def superEggDrop(self, K: int, N: int) -> int:
        dp = [0] * (K + 1)
        step = 0
        while dp[K] < N:
            for i in range(K, 0, -1):
                dp[i] += (1+ dp[i-1]);
            step += 1
        return step

既然是解析,还是要talk talk。

首先,这是一个动态规划问题
有 K 个鸡蛋, N层楼
有一种动态规划方法是用 dp[k][n] 表示拥有K个鸡蛋,N层楼时最少扔的次数
参见动态规划法(六)鸡蛋掉落问题(一)(egg dropping problem)
但是上述方法时间复杂度太高,leetcode超时。

另一种思路是把 dp[step][k] 表示k个鸡蛋扔step次最多能够确定多高(N)楼的临界点
如果step=0,则不能确定任何N高的楼因此dp第一行为0
如果鸡蛋k=0,则不能确定任何N高的楼因此dp第一列为0

对于任意的 dp[step][k], (step, k>1),即有k个鸡蛋扔step次的结果

f层扔一次之后(不关心在第几层扔),还能扔的次数为step-1,并且这个鸡蛋有可能碎掉,也有可能不碎。
在这里插入图片描述
因为鸡蛋只可能出现碎或者不碎两种情况:

  1. 鸡蛋碎了,鸡蛋数为k-1,再考虑下层,下层为子问题 dp[step-1][k-1]
  2. 鸡蛋不碎,鸡蛋数仍为k,再考虑上层,上层子问题为 dp[step-1][k]
  3. 再加上当前楼层 f 最终能确定的最大楼层高度为: dp[step-1][k-1] + dp[step-1][k] + 1

得到动态规划的递推公式:
d p [ s t e p ] [ k ] = d p [ s t e p − 1 ] [ k − 1 ] + d p [ s t e p − 1 ] [ k ] + 1 dp[step][k] = dp[step-1][k-1]+dp[step-1][k]+1 dp[step][k]=dp[step1][k1]+dp[step1][k]+1
一开始为有个疑问是”为什么不是上层与下层的最大值加 1
后来想了很久,因为摆在我们面前的楼是一个黑盒,我们不能确定F是在上层还是下层或者是f层。我们要保证能确定F的次数,必须要考虑所有的情况,即上层下层和f层之和。

有了递推公式,代码就好写了因为题目只需要求step的大小。因此可以直接将step放到最外层循环, dp[k]表示当前step下扔k次鸡蛋能确定的最大N。 当dp[K] >= N时,表明当前step下,扔K个鸡蛋已经能够满足大于等于N层楼的条件,即可退出,当前step为所求答案。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值