最长上升子序列 O(nlogn)
题意:求一个序列中的最长上升子序列。
平常我用的是N*N做法,但是一遇到需要nlogn时,就被卡的无地自容了。
所以下定决心要学习nlogn做法。
如何实现nlongn哪?
这里要用到一个栈B,记录按照时间顺序输入的一个上升子序列。
每输入一个数a就放入栈中,如果a>B[top] ,就放在下一位(B[++top]=a)
如果a<B[top],在栈中找到一个最小的大于等于a的b,(找到一个下限)。让栈内部的数更新变小,以期装更多的数。
最后栈的高度就是最长上升子序列的长度。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<queue> #include<math.h> using namespace std; int maxn,n,a[100009],B[100009],cnt; int find(int x) { int l,r,mid; l=0,r=cnt; while(l<=r) { mid=(l+r)/2; if(B[mid]>=x) r=mid-1; else l=mid+1; } return l; } int main() { // freopen("sort.in","r",stdin); // freopen("sort.ans","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); B[0]=-1;cnt=0; for(int i=1;i<=n;i++) { if(a[i]>B[cnt]) B[++cnt]=a[i]; else{ int t=find(a[i]); B[t]=a[i]; } } cout<<cnt; return 0; }