LeetCode887 - Super Egg Drop - Hard (Python)

这是labuladong的文章总结。

这是一题经典的DP问题,DP的框架为首先思考这个问题有什么状态,有哪些选择,最后根据情况穷举所有可行解。

这题的状态即为当前拥有的鸡蛋数k以及当前所在的楼层数n。选择是我们选择去哪一层楼扔鸡蛋。由状态和选择我们可以得到相对应的转移方程(因为有两个状态,鸡蛋数以及楼层数,所以我们可以考虑用二维的数组):

dp[k][i] = min(dp[k][i], max(dp[k-1][i-1], dp[k][n-i]) 在i层楼扔鸡蛋,鸡蛋可能碎也可能不碎(状态转移方程从这里产生!!!以后遇到对每一步都有两个状态的题,可以多思考,看是否是DP)。如果鸡蛋碎了,那么我们可以用的鸡蛋数就要-1, 因为我们此时只有k-1个鸡蛋了。楼层变为了1....i- 1.(dp[k-1][i- ]) 如果鸡蛋没碎,那么当前我们有的鸡蛋还是k个,但是楼层变成了i+1...n(dp[k][n-i])。 所以dp[k][i] 等于这两种情况的最大值+1.(记得要+1, 因为我们需要执行在i层k个鸡蛋扔鸡蛋的动作),把这两个状态的最大值和dp[k][i] 进行对比。

时间复杂度:动态规划算法的时间复杂度是子问题个数 * 函数本身的复杂度。子问题个数是K*N, 因为是两种状态的组合。函数本身的复杂度,是一个for遍历,O(N)。所以是O(K*N^2)

空间复杂度:子问题的个数 O(KN)

但是这种最直接的解法会超时。

class Solution:
    def superEggDrop(self, K: int, N: int) -> int:

        self.memo = {}
        return self.dp(K, N)

    def dp(self, K, N):
        if (K, N) in self.memo:
            return self.memo[(K, N)]

        if K == 1: return N
        if N == 0: return 0 

        res = float(‘inf‘)
        for i in range(1, N+1):
            res = min(res, max(self.dp(K-1, i-1), self.dp(K, N-i)) + 1)

        self.memo[(K, N)] = res
        return res 

优化版本。

在上述方法的基础上,我们可以观察到dp(k-1, i-1) dp(k, n-i) 这两个函数在k和n确定的情况下是关于i的单调函数,其中前者是单调增,后者是单调减函数。那么当这两个函数相交的时候,即为

min(max(self.dp(k-1, i-1), self.dp(k, n-i))。

class Solution:
    def superEggDrop(self, K: int, N: int) -> int:

        self.memo = {}
        return self.dp(K, N)

    def dp(self, K, N):
        if (K, N) in self.memo:
            return self.memo[(K, N)]

        if K == 1: return N
        if N == 0: return 0 

        res = float(‘inf‘)

        l = 1
        r = N

        while l <= r:
            mid = l + (r-l) // 2
            broke = self.dp(K-1, mid-1)
            not_broken = self.dp(K, N-mid)
            if broke > not_broken:
                r = mid -1
                res = min(res, broke+1) # 注意是取max(broke, not_broken)
            else:
                l = mid + 1
                res = min(res, not_broken+1)
        self.memo[(K, N)] = res
        return res 

时间复杂度:子问题的个数 * 函数本身的复杂度。子问题的个数是k * n, 函数本身的复杂度是二分法O(logn). O(KN*Logn).

空间复杂度:子问题的个数 O(KN).

原文地址:https://www.cnblogs.com/sky37/p/12247772.html

时间: 2024-10-07 23:24:18

LeetCode887 - Super Egg Drop - Hard (Python)的相关文章

Leetcode 887. Super Egg Drop

Problem: You are given K eggs, and you have access to a building with N floors from 1 to N. Each egg is identical in function, and if an egg breaks, you cannot drop it again. You know that there exists a floor F with 0 <= F <= N such that any egg dr

Super Egg Drop

一道陈题. 100 层楼 2 个玻璃球 起因是窥室友手机屏, 看到他群里有人问一个经典问题. 两个一模一样的玻璃球, 两个玻璃球如果从一定高度掉落到地上会被摔碎, 如果在这个高度以下往下扔怎么都不会碎, 现在已知这个恰巧摔碎的高度范围在 1 层楼到 100 层楼之间, 如何用最少的试验次数, 用这两个玻璃球测试出玻璃球恰好摔碎的楼高呢?1 当只剩 1 个球时, 只能一层一层往上测试. 第 1 个球的任务是减少第 2 个球所需测试的次数. 直观上讲, 第 1 个球测试点的间隔要越来越小, 这样第

【LeetCode】动态规划(下篇)

[600] Non-negative Integers without Consecutive Ones [629] K Inverse Pairs Array [638] Shopping Offers [639] Decode Ways II [646] Maximum Length of Pair Chain [647] Palindromic Substrings [650] 2 Keys Keyboard [651] 4 Keys Keyboard [656] Coin Path [6

【LeetCode】数学(共106题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [2]Add Two Numbers [7]Reverse Integer [8]String to Integer (atoi) [9]Palindrome Number [12]Integer to Roman [13]Roman to Integer [29]Divide Two Integers [43]Multiply Strings [50]Pow(x,

【LeetCode】动态规划(上篇共75题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [5] Longest Palindromic Substring 给一个字符串,需要返回最长回文子串 解法:dp[i][j] 表示 s[i..j] 是否是回文串,转移方程是 dp[i][j] = 1 (if dp[i+1][j-1] = 1 && s[i] == s[j]),初始化条件是 if (s[i] == s[j] && (i == j

【LeetCode】动态规划(下篇共39题)

[600] Non-negative Integers without Consecutive Ones [629] K Inverse Pairs Array [638] Shopping Offers [639] Decode Ways II [646] Maximum Length of Pair Chain [647] Palindromic Substrings [650] 2 Keys Keyboard [651] 4 Keys Keyboard [656] Coin Path [6

【LeetCode】二分 binary_search(共58题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [4]Median of Two Sorted Arrays [29]Divide Two Integers [33]Search in Rotated Sorted Array [34]Find First and Last Position of Element in Sorted Array [35]Search Insert Position [50]Pow(

python egg

经常接触Python的同学可能会注意到,当需要安装第三方python包时,可能会用到easy_install命令.easy_install是由PEAK(Python Enterprise Application Kit)开发的setuptools包里带的一个命令,它用来安装egg包.egg包是目前最流行的python应用打包部署方式.如何制作和安装egg包?下面我就简单的分析了一下. 1.1   安装setuptools 首先要安装setuptools工具.Debian/Ubuntu下可以直接使

what&#39;s the python之面向对象

编程分为面向过程和面向对象,首先我们要了解什么是面向对象. 面向对象 面向过程就是我们之前学的内容,主要是函数式,其核心是过程,过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可. 缺点是:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身. 应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等. 面向对象的