找出一维数组中的最长递增子序列 也就是找到一个标号的序列b[0],b[1],...b[m](0<=b[0]<=b[1]<.....b[m]) 使得a[b[0]]<a[b[1]]<.....a[b[m]].
方法一:
从i开始 遍历先前所有的递增子序列 判断当前的a[i] 与最长子序列中的每一个元素的大小 如果满足递增则将i加入
int *LS=new int[n];
for(int i=0;i<n;i++)
{
LS[i]=1;
for(int j=0;j<i;j++)
{
if(a[i]>a[j] && LS[j]+1 > LS[i])//LS[[j]+1 > LS[i] 保证选出的是最长的递增子序列
LS[i]=LS[j]+1;
}
}
时间复杂度为O(N*N)
方法二:
找到前i个元素中的一个递增子序列 使得这个递增子序列的最大元素比a[i+1]小且长度尽量的长这样将a[i+1]加在该递增子序列后便可以找到以a[i+1]为最大元素的最长子序列
假设 长度为1的递增子序列最大元素的最小值为MV【1】
长度为2 的递增子序列最大元素的最小值为MV【2】
。。。。
长度为LS[i]的递增子序列最大元素的最小值为MV【LS】
<pre name="code" class="cpp">int findsum(int *A, int n)
{//计算以A[n]结尾的最大和
if (n == 0)//只有一个数~
return A[n];
if (findsum(A, n - 1) <= 0)//前面n-1个数的最大和小于0~
return A[n];
return findsum(A, n-1)+A[n];//前面n-1个数的最大和大于0
}
方法三:
在递增序列中如果有 i<j 那么 MV[i]<MV[j] 不会出现 MV[j]<MV[i]
因此根据单调性 可以将上面查找小于当前元素的最长递增子序列最后一个元素段改为
for(j=LS[i-1];j>=1;j--)
if(a[i]>MV[j])//找出最长递增子MAXLS序列中结尾元素 与当前元素比较
{
LS[i]=j+1;
break;
}
如果改用二分查找
则时间复杂度为O(N*logN)