每日一题-354. 俄罗斯套娃信封问题 (补昨日)

目录

题目

给你一个二维整数数组 envelopes ,其中 envelopes[i] = [wi, hi] ,表示第 i 个信封的宽度和高度。
当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。
请计算 最多能有多少个 信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。

链接

tga:动态规划 二分查找

题解

学习自官方题解

class Solution {
public:
    int maxEnvelopes(vector<vector<int>>& envelopes) {
        int n=envelopes.size();
        if(n==0)
            return 0;

        sort(envelopes.begin(),envelopes.end(),[](const auto& a,const auto& b){
            return a[0]<b[0] || ((a[0]==b[0])&&a[1]>b[1]);
        });

        vector<int> f(n,1);  //记录最长严格单调递增子序列

        for(int i=1;i<n;i++){
            for(int j=0;j<i;j++){
                if(envelopes[i][1]>envelopes[j][1]){
                    f[i]=max(f[i],f[j]+1);
                }
            }
        }
        return *max_element(f.begin(),f.end());
    }
};
  1. 首先从一维的角度进行简化思考:
    如果仅考虑h,且从题目角度需要满足$h_i < h_j$,才可以进行“装入”的操作
  2. 但是数据可能存在等于关系,再次简化思考:
    假设所有数据都只有不等关系,则对一维上的俄罗斯套娃信封问题,只需求最长递增子序列
  3. 回到本题,我们着手于最长递增子序列,且排除数据等于关系的影响
    即:我们必须要保证对于每一种 w 值,我们最多只能选择 1 个信封。

因此我们就可以得到解决本题需要的方法:

  • 首先我们将所有的信封按照 w 值第一关键字升序、h 值第二关键字降序进行排序;
  • 随后我们就可以忽略 w维度,求出 h 维度的最长严格递增子序列,其长度即为答案。

第二关键字的降序,导致求解最长严格递增子序列时可以排除相等数据的影响
[1,4] [1,3] [1,2] [1,1] [2,4]的最长严格递增子序列为2

  1. 二维的最长严格单调递增子序列
        vector<int> f(n,1);  //记录最长严格单调递增子序列

        for(int i=1;i<n;i++){
            for(int j=0;j<i;j++){
                if(envelopes[i][1]>envelopes[j][1]){
                    f[i]=max(f[i],f[j]+1);
                }
            }
        }

从0到i的数据,f中记录着其最长调度递增子序列长度
f[i]=max(f[i],f[j]+1) f[i]满足题目关系中的递增于f[j]

上一篇:算法提高 P1001(大数相乘)


下一篇:蓝桥杯 Torry的困惑(基本型) C++算法训练 HERODING的蓝桥杯之路