/* 主要思想: 对于任意长度的递增序列都维护一个结束的最小值, ** 这里是max, maxIndex代表当前具有的最大长度,比如我们现在求LIS(i), 此时max数组里面可能存有一些长度是不存在的。我们把这些不存在的长度设置为最大值。 把0设置为最小值,对于每个元素a[i],从最长的maxIndex开始往下比较,找到第一个比max[j]大的数 j。 由于长度为j的序列<a[i],所以可知以a[i]结尾的最长递增子序列可以为j+1,此后我们更新维护的 max数组,及其下标maxIndex. */ int LongIncreaseSubString(int a[],int n) { int max[100]; int maxIndex; // 参考编程之美, max[1]=a[0]; // max[0]=0x80000000; maxIndex=1; int lis[100]; lis[0]=1; int i,j; for(i=1;i<=n;i++) { max[i]=0x7fffffff; } for( i=1;i<n;i++) { /*for( j=maxIndex;j>=0;j--) { if(a[i]>max[j]) { lis[i]=j+1; break; } }*/ int m=0,n=maxIndex; while(m<n-1) { int mid=m+(n-m)/2; if(max[mid]>a[i]) n=mid-1; else if(max[mid]<a[i]) { m=mid; } else m=mid-1; } if(m==n) { lis[i]=m+1; } else { if(a[i]<a[n]) lis[i]=m+1; else lis[i]=n+1; } if(lis[i]>maxIndex) { maxIndex=lis[i]; max[lis[i]]=a[i]; } else { max[lis[i]]=min(max[lis[i]],a[i]); } } return maxIndex; } int main(void) { int a[]={1,-1,2,-3,4,-5,6,-7}; cout<<LongIncreaseSubString(a,8)<<endl; system("pause"); return 0; }