leetcode 354 二维最长递增子序列+二维最长不递减子序列

在这里插入图片描述
最长递增子序列
第一维从小到大,第一维相等从大到小
对第二维做最长上升子序列
维护一个增长子序列数组
这里要用lower_bound找到第一个大于等于把它替换掉

*lower_bound(dp,dp+n+1,nums[i][1])=nums[i][1];

这样就能排序掉第一维相等的情况,保证每一维都大于之前的选择

最长不递增
第一维从小到大,第一维相等从小到大
对第二维做最长上升子序列,每一维大于等于之前
维护一个增长子序列数组
这里要用upper_bound找到第一个大于把它替换掉,因为可以等于所以需要把等于也加入答案

*upper_bound(dp,dp+n+1,nums[i][1])=nums[i][1];

最长严格递增

class Solution {
public:
    static bool cmp(vector<int> &a,vector<int> &b)
    {
        if(a[0]==b[0]) return a[1]>b[1];
        return a[0]<b[0];
    }
   
    int maxEnvelopes(vector<vector<int>>& nums) {
        int n=nums.size();
        sort(nums.begin(),nums.end(),cmp);
        int dp[n+1];
        fill(dp,dp+n+1,INT_MAX);
        for(int i=0;i<n;i++)
        {
            *lower_bound(dp,dp+n+1,nums[i][1])=nums[i][1];
        }
        return lower_bound(dp,dp+n+1,INT_MAX)-dp;

    }
};

第一维不递减(可以有等于),二维递增

#include <bits/stdc++.h>
#define show(a, b) cout << a << " " << b << endl;
#define show3(a, b, c) cout << a << " " << b << " " << c << endl;
using namespace std;

#define ll long long
const int N = 1e6 + 5;
int n, k, m, a[N], ans;
int cnt = 0;
string s;
vector<int> mp;
int dp[N];
int num[N];
bool vis[N];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> n;
    vector<vector<int>> num(n, vector<int>(2, 0));
    for (int i = 0; i < n; i++)
        cin >> num[i][0] >> num[i][1];
    sort(num.begin(),num.end(),[](vector<int> &a,vector<int> b){
        if(a[0]==b[0]) return a[1]<b[1];
        return a[0]<b[0];
    });


    fill(dp, dp + n + 1, INT_MAX);
    for (auto v : num)
    {
        int x = v[1];
        *lower_bound(dp, dp + n + 1, v[1]) = v[1];
    }


    cout<< lower_bound(dp,dp+n+1,0x3f3f3f3f)-dp;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值