leetcode887. 鸡蛋掉落 谷歌经典面试题的一般情况

该博客探讨了使用动态规划解决LeetCode 887题——超级鸡蛋掉落问题。内容涉及不同数量鸡蛋和楼层情况下,求解最坏情况下的最小测试次数。介绍了两种思路,一种基于递推关系,另一种通过尝试次数来计算能到达的最大楼层,最后给出了两种方法的时间复杂度分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

leetcode887

题意:用k个蛋测试n层楼的f值,求最坏情况(所有蛋碎蛋不碎的情况中)最小测试次数f值表示在f及以下层蛋扔下去都不会碎,之上都会碎。

一、一个蛋的情况
只能从1楼逐层往上尝试,结果为楼层数。
二、2个蛋的情况(谷歌面试题的形式)

100层楼为例:
将楼层分为10等分,1,10,20,30…100
A操作是测试1, 10, 20, 30… 100 扔下,蛋是否会碎掉
B操作是从x1,x2,x3…x9逐层测试蛋是否碎

当A操作不碎,一直进行A;
当A操作在碎掉,就在之前的9层逐层尝试;
故最坏情况是100层碎掉,逐层尝试91…99
19次(10次A,9次B操作)。

三、 无穷个蛋
蛋就不需要考虑了,结果就是楼层数的二分。

四、一般情况,n层楼,k个蛋

dp[n][k] : n层楼k个鸡蛋最坏情况能得到f值的最小尝试次数
由上面讨论知:
dp[1][k] = 1
dp[n][1] = n

在这里插入图片描述

对于1-N层楼的任意K点
若K处鸡蛋碎了,则问题转化为dp[K-1][j-1];
若K处鸡蛋没碎,则转化为求dp[N-K][j] .
因为要最坏情况,所以取最大值,再+1(K点的尝试次数)。

因为蛋碎不碎是不可控的,所以要取max,而K的点却是可以控制的(枚举到的位置是确定的),故取min。

由于K点是任意的,故要枚举K点位置
时间复杂度O(n * n * k)

 //O(n*n*k)
    int superEggDrop(int k, int n) {
        // dp[i][j] : i层楼j个鸡蛋最坏情况能得到f值的最小尝试次数
       vector<vector<int>>dp(n+1, vector<int>(k+1, 0));

       for(int j = 1; j <= k; ++j) dp[1][j] = 1;
       for(int i = 1; i <= n; ++i) dp[i][1] = i;
        for(int i = 2; i <= n; ++i) {
            for(int j = 2; j <= k; ++j) {
                dp[i][j] = dp[i][j-1];
                for(int K = 1; K <= i; ++K) {
                    dp[i][j] = min(dp[i][j], max(dp[K-1][j-1], dp[i-K][j]) + 1);
                }
            }
       }
       return dp[n][k];
    }

思路二:
dp[i][i] : j个鸡蛋做i次尝试最多能在dp[i][j]层楼中得到f

dp[i][j] = dp[i-1][j-1] + dp[i-1][j] + 1
(尝试一次之后(1)+ 尝试i-1次楼层下面最高的楼层+ 上面最高能达到的楼层)
时间复杂度O(n*k)
在这里插入图片描述

    int superEggDrop(int k, int n) {
        // dp[i][j] : j个鸡蛋做i次尝试最多能在dp[i][j]层楼中得到f
        // dp[i][j] = dp[i-1][j-1] + dp[i-1][j] + 1
       vector<vector<int>>dp(n+1, vector<int>(k+1, 0));
       for(int i = 1; i <= n; ++i) {
           for(int j = 1; j <= k; ++j) {
               dp[i][j] = dp[i-1][j-1] + dp[i-1][j] + 1;
           }
           if(dp[i][k] >= n) return i;
       }
       return n;
    }

Reference:
李永乐老师讲解双蛋问题
AcWing

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值