/* 主要思想: 对于任意长度的递增序列都维护一个结束的最小值,
** 这里是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;
}