标签:stream else 数字 lis 因此 ret ios 二分 clu
O(nlogn)
q[i]表示所有不同长度的最长上升子序列结尾的最小值。因为如果a[i]<a[j]<a[j+1],那么a[j+1]肯定大于a[i],因此我们只存最小值。
我们通过第i-1个数字来划分状态,由于子序列是递增的,所以可以通过二分查找出来小于a[i]的最大的那个数字。找到之后,将a[i]放在它之后,长度加一。并且由于子序列是递增的,那么若找到的数字为a[k],那么a[k+1]一定大于等于a[i]。所以可以用a[i]来更新a[k+1].
#include<iostream> #include<cmath> using namespace std; const int maxn=1e5+10; int a[maxn]; int q[maxn];//所有不同长度的最长上升子序列结尾的最小值 int main() { int n; cin >> n; for(int i=0;i<n;i++) { cin >> a[i]; } int len=0;//最长上升子序列的长度 //q[0]=-2e9; for(int i=0;i<n;i++) { int l=0,r=len; while(l<r) { int mid=l + r + 1>> 1; if(q[mid]<a[i]) l=mid; else r=mid-1; } len=max(len,r+1); q[r+1]=a[i]; } cout << len << endl; return 0; }
标签:stream else 数字 lis 因此 ret ios 二分 clu
原文地址:https://www.cnblogs.com/wjc2021/p/11938811.html