您的位置:首页 > 其它

最长递增子序列(O(nlogn))

2015-08-15 10:23 232 查看
使用最基础的方法计算最长递增子序列的时间复杂度为O(n^2),

在n值过大时,肯定会超时。因此,在这里介绍一种优化算法。

维护一个一维数组dp,dp[i]表示最长上升子序列长度是i的所有子串中末尾最小的那个数,根据这个数字,我们可以比较知道,只要当前考察的这个数比dp[i]大,那么当前这个数一定能通过dp[i]构成一个长度为i+1的上升子序列。当然我们希望在dp数组中找一个尽量靠后的数字,这样我们得到的上升子串的长度最长,查找的时候使用二分搜索,这样时间复杂度便下降了。

可能解释的不太好,那么还是把代码发出来吧

Talk is cheap,show me the code.

#include<iostream>
#include<stdio.h>
#include<queue>
#include<stack>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
int num[40005];
int dp[40005];
using namespace std;
int main()
{   int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
}
int len=1;
dp[1]=num[1];
for(int i=2;i<=n;i++)
{
if(num[i]>dp[len])
{
len++;
dp[len]=num[i];
continue;
}
int pos=lower_bound(dp+1,dp+len+1,num[i])-dp;
dp[pos]=num[i];
}
printf("%d\n",len);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: