题目描述
Description
给一个数组a1, a2 ... an,找到最长的上升降子序列ab1<ab2< .. <abk,其中b1<b2<..bk。
输出长度即可。
输入描述
Input Description
第一行,一个整数N。
第二行 ,N个整数(N < = 5000)
输出描述
Output Description
输出K的极大值,即最长不下降子序列的长度
样例输入
Sample Input
5
9 3 6 2 7
样例输出
Sample Output
3
我们都知道,对于简单的上升子序列,我们可以直接通过O(n²)求解,但对于数据比较大的情况显然不行。下面给出大家O(nlogn)的办法。通过二分来查找更新,不断加入或者替换,使得序列一直是最优的序列(得到的结果并不是真正的上升子序列)。比如1 4 5 2 6。代码最后得到的结果应该是1256,正确的上升子序列应该是1456。具体原因大家细细理解,我怕说的不清反而误导。
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
int a[5005];
int main()
{
int n, c, t = 0;
cin >> n;
for(int i = 1; i <= n; i++)
{
scanf("%d", &c);
if(c > a[t])
{
a[++t] = c;
}
else
{
int s = 1, e = t;
while(s < e)
{
int mid = (s + e) / 2;
if(a[mid] < c)
s = mid + 1;
else
e = mid;
}
a[s] = c;
}
}
cout << t << endl;
return 0;
}