【動的計画法-ソリティア型(一次元座標型)】Lintcode602。ロシアンドール封筒

Lintcode602。マトリョーシカ封筒

タイトルの説明:特定の数の封筒を指定します。整数のペア(w、h)は、それぞれ封筒の幅と高さを表します。一方の封筒の幅と高さがもう一方の封筒よりも大きい場合は、別の封筒を下に置くことができます。エンベロープネスティングレベルの最大数を見つけます。
ここに画像の説明を挿入
この質問が最も一般的なアイデア([動的計画法-ソリティア(1次元座標型)] Lintcode 76.最長昇順サブシーケンスと同様)で処理される場合、ループが2層あるため、時間計算量は時間の経過とともに複雑になります。特定の最適化を通じて、元のアルゴリズムの第2レベルのループを削除する必要があります。

ここでは、最初に一般的な方法を示し(時間計算量を超え、ACは不可能)、次に最適化された方法を示します。

//1. 普通方法,时间复杂度会超
class Solution {
    
    
public:
    /**
     * @param envelopes: a number of envelopes with widths and heights
     * @return: the maximum number of envelopes
     */
    int maxEnvelopes(vector<vector<int>> &envelopes) {
    
    
        if (0 == envelopes.size()) {
    
    
            return 0;
        }

        //1. 按第一维排序
        sort(envelopes.begin(), envelopes.end());

        //2. 对第二维使用接龙型动态规划
        //2.1 初始化
        vector<int> f(envelopes.size(), 1);//任何一个位置都可能是起始位置

        //2.2 状态转移
        for (int i = 1; i < envelopes.size(); ++i) {
    
    
            for (int j = 0; j < i; ++j) {
    
    
                if (envelopes[j][1] < envelopes[i][1] && 
                envelopes[j][0] < envelopes[i][0]) {
    
    
                    f[i] = max(f[i], f[j] + 1);
                }
            }
        }

        //2.3 答案
        auto maxPlies = max_element(f.begin(), f.end());
        return *maxPlies;
    }
};


//2. 进行了优化,可以通过OJ
class Solution {
    
    
public:
    /**
     * @param envelopes: a number of envelopes with widths and heights
     * @return: the maximum number of envelopes
     */
    int maxEnvelopes(vector<vector<int>> &envelopes) {
    
    
        if (envelopes.empty()) {
    
    
            return 0;
        }
        
        sort(envelopes.begin(), envelopes.end(), cmp);
        int n = envelopes.size();
        vector<int> dp;
        for (int i = 0; i < n; i++) {
    
    
            auto it = lower_bound(dp.begin(), dp.end(), envelopes[i][1]);
            if (it == dp.end()) {
    
    
                dp.push_back(envelopes[i][1]);
            }
            else {
    
    
                *it = envelopes[i][1];
            }
        }
        return dp.size();
    }
    
    static bool cmp(vector<int> &a, vector<int> &b) {
    
    
        if (a[0] == b[0]) {
    
    
            return a[1] > b[1];
        }
        return a[0] < b[0];
    }
};

おすすめ

転載: blog.csdn.net/phdongou/article/details/114207247