数组编号1~n
扫描所求序列a[],并将a[]的数依次插入dp[]数组,dp[]数组的长度len
如果dp[]的末尾元素dp[len]小于当前扫描的数a[i],则将该数加入在末尾。
否则,在dp[]数组中找到第一个大于或者等于a[i]的位置,放置a[i];
a[]扫描完毕后,len就是答案
在查找dp[]数组中第一个大于或者等于a[i]的位置时可以用二分查找,时间复杂度logn
#include <cstdio>
using namespace std;
const int maxn = 100010;
const int INF = 2147483640;
int a[maxn];
int dp[maxn];
int bin_find(int key, int l, int r);
int main()
{
int n;
while(~scanf("%d", &n))
{
for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
int len = 0, pos;
dp[0] = -INF;
for(int i = 1; i <= n; ++i)
{
if(a[i] > dp[len]) dp[++len] = a[i];
else
{
pos = bin_find(a[i], 1, len);//第一个大于或者等于它的位置
dp[pos] = a[i];
}
}
printf("%d\n", len);
}
return 0;
}
int bin_find(int key, int l, int r)
{
int mid;
while(l <= r)
{
mid = (l + r)>>1;
if(key <= dp[mid]) r = mid - 1;
else l = mid + 1;
}
return r + 1;
}