方法一:普通动态规划算法,时间复杂度O(n2)。
int LIS(int a[], int n)
{
int i, j, k;
int maxlen;
int *b=new int[n];
for(i=0, b[0]=1; i<n; i++)
{
for(j=0, k=0; j<i; j++)
{
if(a[j]>a[i] && k<b[j])
k=b[j];
b[i]=k+1;
}
}
maxlen=0;
for(i=0; i<n; i++)
if(b[i]>maxlen)
maxlen=b[i];
return maxlen;
}
int main()
{
int a[]={9,4,3,2,5,4,3,2};
cout<<LIS(a, 8)<<endl;
}
方法二:采用二分搜索算法,时间复杂度O(nlgn)。
0<=i<n,k是序列a[0:i]的最长单调递减子序列的长度。b[k]是序列a[0:i]中所有长度为k的递减子序列中的最大结尾元素值。
在由i-1到i的循环中,如果a[i]<b[k],则k++,b[k]=a[i];否则k值不变,但要更新b数组。怎么更新b数组呢?如果a[i]>b[1],则b[1]=a[i];若a[i]<b[1],注意到数组b是递减的,则二分搜索找到b[j-1]>a[i]>b[j],更新b[j]=a[i]。