如:1,-1,2,-3,4,-5,6,-7中,最长递增子序列是1,2,4,6.数组
【解法1】spa
假设在目标数组array[]的前i个元素中,最长递增子序列的长度为LIS[I],code
那么对于任意k<=i,当array[i+1]>array[k]时,LIS[i+1]=LIS[K]+1,不然LIS[i+1]=1。blog
此法特色:在考虑第i+1个元素的时候不考虑前面i个元素的状况。class
代码:di
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】co
对于前面i个元素的任何一个递增子序列,若是这个子序列的最大元素比array[i+1]小,那么就能够将array[i+1]加在这个子序列后面,构成一个新的递增子序列。let
所以,要找到前i个元素中的一个递增子序列,使得这个递增子序列的最大的元素比array[i+1]小,且长度尽可能长。这样即可找到以array[i+1]为最大元素的最长递增子序列。new
假设:return
在数组前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; }