求最长递增子序列

/* 主要思想: 对于任意长度的递增序列都维护一个结束的最小值,

**  这里是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;
}

  

posted on 2013-08-17 21:32  dyc0113  阅读(208)  评论(0编辑  收藏  举报

导航