LIS 最长严格上升子序列问题

来源:互联网 发布:android ui 设计软件 编辑:程序博客网 时间:2024/05/17 04:59

复习系列

dp做到O(n^2)

二分做到O(nlogn)

具体讲二分

用L[x]数组表示 长为x的序列末尾的数(也就是最大的)

容易得到 L数组单调上升

那么每次读入一个数a时 都可以在L数组里找到比a大的最小的位置

显然这个位置如果是a的话应该是更优的

那用a替换掉它

贴码

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>#include<cstdlib>#include<cmath>#include<map>#include<set>#define ll long longusing namespace std;ll read(){    ll ans=0;    bool b=1;    char c=getchar();    while(!isdigit(c))    {        if(c=='-')b=0;        c=getchar();    }    while(isdigit(c))    {        ans=ans*10+(c-'0');        c=getchar();    }    if(b)return ans;    else return -ans;}int L[1000001],p;int main(){    //ios::sync_with_stdio(false);    int n=read();    for(int i=1;i<=n;i++)    {        int a=read();        int l=0,r=p,mid=(l+r)>>1;        while(l<r)        {            mid=(l+r)>>1;            if(a>L[mid])l=mid+1;            else r=mid;        }        if(L[l]>=a)L[l]=a;        else L[++p]=a;    }    cout<<p;    return 0; }
原创粉丝点击