您的位置:首页 > 其它

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

2017-05-25 19:41 399 查看
复习系列

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 long
using 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LIS