dp最长上升子序列(单调队列优化)

给定一个长度为N的数列,求数值严格单调递增的子序列的长度最长是多少。(N <= 1e5)

朴素做法时间复杂度O(n^2)过不了
用单调队列的思想优化可以O(nlongn)


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int Ull;
const ll N = 1e5+10;
int arr[N];
int main(){
    //ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0); 
    //用单调队列的思想,V[i]的位置存长度为i的递增序列最后一个数的最小值
    //可知,V 是递增的。
    //遍历原数组,若arr[i]大于队尾元素则入队列(说明当前维护的最长序列长度可以加一),
    //否则就用arr[i]替换V中第一个大于等于arr[i]的值(若该值是V[j],说明V[j-1]严格小于arr[i],V[j]大于等于arr[i],
    //则j长度的递增序列的最后一个数更新为arr[i])
    //lower_bound用二分的方法从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end
    int n;
    cin>>n;
    for(int i = 1; i <= n; i++) cin>>arr[i];
    vector<int> V;
    for(int i = 1; i <= n; i++){
        if(V.size() == 0) V.push_back(arr[i]);
        else{
            if(arr[i] > V.back()) V.push_back(arr[i]);
            else *lower_bound(V.begin(),V.end(),arr[i]) = arr[i];
        }
    }
    cout<<V.size()<<endl;
} 

 
posted @ 2020-12-04 15:10  CamusJohnson  阅读(427)  评论(0)    收藏  举报