一道蛮好的题~~求最长非降序子序列的长度,因为数据是40000,如果用经典的O(n^2)就会TLE。 在网上搜到了一中nlgn的,不错。
很好理解的一种算法。在n^2的基础上,仔细地考虑每一步就可以看出,其实我们要用到的只是找到那个符合比num[i]小的值罢了,所以只要维护好opt就好了。这样就可以用到二分查找算法提高效率。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main()
{
int opt[40000],num[40000],i,j,t,n,m = 0,l,r,mid;
//opt[0] = 0;opt[1] = 1;
scanf("%d",&t);
while(t --)
{
scanf("%d",&n);
m = 0;
memset(opt,0,sizeof(opt));
for(i = 0;i < n;i ++)
scanf("%d",&num[i]);
for(i = 0;i < n;i ++)
{
if(num[i] > opt[m])
opt[++ m] = num[i];
else
{
l = 0;r = m;
while(l < r - 1)
{
mid = (l+r)/2;
if(opt[mid] < num[i])
l = mid;
else r = mid;
}
if(opt[l] < num[i])
opt[r] = num[i];
else
opt[l] = num[i];
}
}
printf("%d\n",m);
}
return 0;
}