题目描述

给定一个长度为nn的数组a1,a2,,ana_1,a_2,…,a_n,问其中的最长上升子序列的长度。

所有数据保证1n100000,1ai1091≤n≤100000,1≤a_i≤10^9

分析

c[i]c[i]:表示上升子序列为ii的最后一个元素的最小值

如果c[len]<a[i]c[len]<a[i],那么c[++len]=a[i]c[++len]=a[i]

否则,从0len0-len进行二分,将a[i]a[i]存入

lenlen为当前最长上升子序列

AC代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n,len,a[maxn],c[maxn];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++){
		if(a[i]>c[len])
			c[++len]=a[i];
		else{
			int l=0,r=len;
			while(l+1<r){
				int mid=(l+r)/2;
				if(c[mid]<a[i])
					l=mid;
				else
					r=mid;
			}
			c[r]=a[i];
		}
	}
	printf("%d",len);
}