如:1,-1,2,-3,4,-5,6,-7中,最长递增子序列是1,2,4,6.
【解法1】
假设在目标数组array[]的前i个元素中,最长递增子序列的长度为LIS[I],
那么对于任意k<=i,当array[i+1]>array[k]时,LIS[i+1]=LIS[K]+1,否则LIS[i+1]=1。
此法特点:在考虑第i+1个元素的时候不考虑前面i个元素的情况。
代码:
int longestSub(int a[], int n) { int *LIS=new int[n]; int max=0; for(int i=0; i<n; i++){ LIS[i]=1; for(int j=0; j<i; j++) if(a[i]>a[j]&&LIS[j]+1>LIS[i]) LIS[i]=LIS[j]+1; if(max<LIS[i]) max=LIS[i]; } delete [] LIS; return max; }
【解法2】
对于前面i个元素的任何一个递增子序列,如果这个子序列的最大元素比array[i+1]小,那么就可以将array[i+1]加在这个子序列后面,构成一个新的递增子序列。
因此,要找到前i个元素中的一个递增子序列,使得这个递增子序列的最大的元素比array[i+1]小,且长度尽量长。这样便可找到以array[i+1]为最大元素的最长递增子序列。
假设:
在数组前i个元素中,以array[i]为最大元素的最长递增子序列的长度为LIS[i]。
长度为i的递增子序列最大元素的最小值为maxV[i]。。。
代码:
int LIS(int a[], int n) { int *maxV=new int[n+1]; int *LIS=new int[n]; int amin=a[0]; for(int i=0; i<n; i++) if (amin>a[i]) amin=a[i]; maxV[1]=a[0]; maxV[0]=amin-1;//边界值 for(int i=0; i<n; i++) LIS[i]=1; int nMaxLIS=1;//最长子序列长度 for(int i=1; i<n; i++) { int j; for(j=nMaxLIS; j>=0; j--) //for(j=LIS[i-1]; j>-1; j--) { if(a[i]>maxV[j]) { LIS[i]=j+1; break; } } if(LIS[i]>nMaxLIS){ nMaxLIS=LIS[i]; maxV[LIS[i]]=a[i]; } else if(maxV[j]<a[i]&& a[i]<maxV[j+1]){ maxV[j+1]=a[i];//更新最大元素最小值 } } return nMaxLIS; }