zoukankan      html  css  js  c++  java
  • LeetCode 887.鸡蛋掉落(C++)

    每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。

    你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。

    每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X <= N)。

    你的目标是确切地知道 F 的值是多少。

    无论 F 的初始值如何,你确定 F 的值的最小移动次数是多少?

    示例 1:

    输入:K = 1, N = 2
    输出:2
    解释:
    鸡蛋从 1 楼掉落。如果它碎了,我们肯定知道 F = 0 。
    否则,鸡蛋从 2 楼掉落。如果它碎了,我们肯定知道 F = 1 。
    如果它没碎,那么我们肯定知道 F = 2 。
    因此,在最坏的情况下我们需要移动 2 次以确定 F 是多少。
    

    示例 2:

    输入:K = 2, N = 6
    输出:3
    

    示例 3:

    输入:K = 3, N = 14
    输出:4
    

    提示:

    1. 1 <= K <= 100
    2. 1 <= N <= 10000

    转载:思路

    根据https://github.com/Shellbye/Shellbye.github.io/issues/42换角度思考得到

    
    

    dp[k][m] 的含义是k个鸡蛋 移动m次最多能够确定多少楼层
    这个角度思考
    dp[k][m] 最多能够确定的楼层数为L
    那么我选定第一个扔的楼层之后,我要么碎,要么不碎
    这就是把L分成3段
    左边是碎的那段 长度是dp[k][m - 1]
    右边是没碎的那段 长度是dp[k-1][m - 1] 因为已经碎了一个了
    中间是我选定扔的楼层 是1
    所以递推公式(状态方程)是

    dp[k][m] = dp[k - 1][m - 1] + dp[k][m - 1] + 1

    根据递推公式 如果采用k倒着从大到小计算 就可以只存一行的dp[k] 直接原地更新dp[k] 不影响后续计算 只需要O(K)空间复杂度 O(KlogN) 鸡蛋完全够用的时候 就是走LogN步 最差情况是1个鸡蛋走N步 O(KN)

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    static int x = []() {std::ios::sync_with_stdio(false); cin.tie(0); return 0; }();
    class Solution {
    public:
        int superEggDrop(int K, int N) {
            vector<int> dp(K + 1, 0);
            int m = 0;
            while (dp[K] < N) {//表示当能够测试的最大楼层数刚好是我们需要的楼层数N时,此时取得m的最小值。
                m++;
                for (int k = K; k > 0; --k) {
                    dp[k] = dp[k - 1] + dp[k] + 1;//逆向遍历,不断更新dp[k],使得dp[k]取最大值(能够测试的最大楼层数)
                }
            }
            return m;
        }
    };
    
    int main()
    {
        Solution A;
        cout << A.superEggDrop(3, 14);
    
        system("PAUSE");
        return 0;
    }
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    class Solution {
    public:
        int superEggDrop(int K, int N) {
            vector<vector<int> > dp(K + 1, vector<int>(N, 0));
            int m = 0;
            while(dp[K][m] < N){
                ++m;
                for(int i = K; i > 0; i--)
                    dp[i][m] = dp[i - 1][m - 1] + dp[i][m - 1] + 1;
            }
            
            return m;
        }
    };
    
    int main()
    {
        Solution A;
        cout << A.superEggDrop(1, 2);
        
        return 0;
    }
  • 相关阅读:
    设计模式《JAVA与模式》之解释器模式
    设计模式《JAVA与模式》之状态模式
    设计模式《JAVA与模式》之备忘录模式
    设计模式《JAVA与模式》之责任链模式
    设计模式《JAVA与模式》之命令模式
    设计模式《JAVA与模式》之迭代子模式
    iOS-联系人应用(一)
    简易 HTTP Server 实现(JAVA)
    IBM Websphere 集群会话共享问题解决办法
    集群会话共享问题的几种处理方式
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/10574996.html
Copyright © 2011-2022 走看看