算法: 超级落蛋计算第一次蛋碎的楼层887. Super Egg Drop

Posted AI架构师易筋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法: 超级落蛋计算第一次蛋碎的楼层887. Super Egg Drop相关的知识,希望对你有一定的参考价值。

887. Super Egg Drop

You are given k identical eggs and you have access to a building with n floors labeled from 1 to n.

You know that there exists a floor f where 0 <= f <= n such that any egg dropped at a floor higher than f will break, and any egg dropped at or below floor f will not break.

Each move, you may take an unbroken egg and drop it from any floor x (where 1 <= x <= n). If the egg breaks, you can no longer use it. However, if the egg does not break, you may reuse it in future moves.

Return the minimum number of moves that you need to determine with certainty what the value of f is.

Example 1:

Input: k = 1, n = 2
Output: 2
Explanation: 
Drop the egg from floor 1. If it breaks, we know that f = 0.
Otherwise, drop the egg from floor 2. If it breaks, we know that f = 1.
If it does not break, then we know f = 2.
Hence, we need at minimum 2 moves to determine with certainty what the value of f is.

Example 2:

Input: k = 2, n = 6
Output: 3

Example 3:

Input: k = 3, n = 14
Output: 4

Constraints:

  • 1 <= k <= 100
  • 1 <= n <= 104

动态规划解法

掉落鸡蛋是一个非常经典的问题。
有些人可能会想出想法O(KN^2)
在那里dp[k][n] = 1 + max(dp[k - 1][i - 1], dp[k][n - i]),因为我在1 ... n
然而,这个想法是非常暴力的,因为你要检查所有的可能性。

所以我以不同的方式考虑这个问题:
dp[m][k]意味着,给定k鸡蛋和m移动,
我们可以检查的最大楼层数是多少。

dp 方程是:
dp[m][k] = dp[m - 1][k - 1] + dp[m - 1][k] + 1
这意味着我们移动到一个楼层,

  1. 如果鸡蛋破了,那么我们可以检查dp[m - 1][k - 1]楼层。
  2. 如果鸡蛋没有破,那么我们可以检查dp[m - 1][k]地板。

dp[m][k] 是组合的数量,它呈指数增长 n

复杂
对于时间, 空间复杂度O(nk),时间复杂度O(klogn),

class Solution 
    public int superEggDrop(int k, int n) 
        int[][] dp = new int[n + 1][k + 1];
        int m = 0;
        while (dp[m][k] < n) 
            ++m;
            for (int i = 1; i <= k; i++) 
                dp[m][i] = dp[m - 1][i - 1] + dp[m - 1][i] + 1;
            
        
        
        return m;
    

优化空间复杂度O(k)

class Solution 
    public int superEggDrop(int k, int n) 
        int[] dp = new int[k + 1];
        int m = 0;
        for (; dp[k] < n; ++m) 
            for (int i = k; i > 0; --i) 
                dp[i] += dp[i - 1] + 1;
            
        
        return m;
    

参考

https://leetcode.com/problems/super-egg-drop/discuss/158974/C%2B%2BJavaPython-2D-and-1D-DP-O(KlogN)

以上是关于算法: 超级落蛋计算第一次蛋碎的楼层887. Super Egg Drop的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode887鸡蛋掉落——dp

887. 鸡蛋掉落(困难)-动态规划

扔鸡蛋

text N层楼K个鸡蛋抛,判断临界点不会碎的楼层,要保证能测出鸡蛋恰好会碎的楼层,并使此策略在最坏情况下所扔次数最少

leetcode困难887鸡蛋掉落

经典面试题楼层丢鸡蛋问题的动态规划解法与数学解法