对于数值范围较大的n求解最长上升序列,用暴力比较肯定不行。那么我们可以用一个dp数组来对这个最长的序列进行标示,其下标代表最长上升序列,dp[top]的值代表满足长度为top的数的最小值。然后依次遍历整个数组a[i]。并且查找a[i],所在dp[]中的位置,返回l,代表a[i]在dp[]中的上升序列值。找到一个和dp[]中相等或小于dp[l]的位置直接将该位置的值赋成a[],然后比较当前的最大长度和返回的位置的关系,如果返回值>当前最大长度,则当前最大长度改为返回长度。
样例输入
7 1 9 10 5 11 2 13 2 2 -1
5 1
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int a[1000000],dp[1000000],n;
int top;
int so(int x)
{
int l=1,r=top;
while(l<=r)
{
int mid=(l+r)>>1;
if(dp[mid]==x)
return mid;
if(dp[mid]<x)
l=mid+1;
else
r=mid-1;
}
return l;
}
int main()
{
int m,i,j;
while(~scanf("%d",&n))
{
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
scanf("%d",&a[i]);
dp[1]=a[0];
top=1;
for(i=1;i<n;i++)
{
int tmp=so(a[i]);
dp[tmp]=a[i];
if(tmp>top)
top=tmp;
}
printf("%d\n",top);
}
return 0;
}