利用了二分的思想来找已经放进去的第一个比读入元素大的位置,然后替换一下就行,如果读入的数比头上的数目还大,那么更新头部,加入一个新的数,最后这个数组的大小就是最长的上升子序列了,复杂度大约nlogn,比传统的n2快了不少;
/*
ID: sdj22251
PROG: calfflac
LANG: C++
*/
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#define MAX 100000000
#define LOCA
#define PI acos(-1.0)
using namespace std;
int a[100001]; //记录数组
int main()
{
#ifdef LOCAL
freopen("ride.in","r",stdin);
freopen("ride.out","w",stdout);
#endif
int n, m, cnt, high, low, mid, i;
while(scanf("%d", &n) != EOF)
{
cnt = 0; //最长序列个数
for(i = 1; i <= n; i++)
{
scanf("%d", &m);
if(cnt == 0 || m > a[cnt]) //如果是第一个或者比队头的大,则存入数组
a[++cnt] = m;
else
{
high = cnt;
low = 1;
while(low <= high) //在已存序列中寻找位置,将输入的数替换进去,这样可以保证一直是上升序列
{
mid = (low + high) / 2;
if(a[mid] < m)
low = mid + 1;
else high = mid - 1;
}
a[low] = m;
}
}
printf("%d\n", cnt);
}
return 0;
}