方法一:普通動態規劃算法,時間複雜度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]。
int LIS(int a[], int n)
{
int i=0, k;
int l, h;
int *b=new int[n+1];
b[1]=a[0];
for(i=1, k=1; i<n; i++)
{
if(a[i]<b[k])
b[++k]=a[i];
else
{//更新b[]
if(a[i]>b[1])
b[1]=a[i];
else
{//二分查找
for(l=1, h=k; l!=h-1; )
{
int mid=(l+h)/2;
if(b[mid]<=a[i])
h=mid;
else
l=mid;
}
b[h]=a[i];
}
}
}
return k;
}
int main()
{
int a[]={9,4,3,2,5,4,3,2};
cout<<LIS(a, 8)<<endl;
}