【编程之美】2.16 求数组中最长递增子序列

问题描述:

写一个时间复杂度尽可能低的程序,求一个一维数组(N个元素)中最长递增子序列的长度。

例如:在序列1,-1,2,-3,4,-5,6,-7中,其最长递增子序列的长度为4(如1,2,4,6)。

问题分析:

该问题满足“无后效性”,可以用动态规划来解决。
设原数组为array[N],假设LIS[i]代表以array[i]为最大元素的最长递增子序列的长度。
那么LIS[i+1] 如何得到?注意到,对于任意的k < i+1,若array[i + 1] > array[k],则LIS[i+1] >= LIS[k] + 1。
事实上,集合{ LIS[K] + 1 | k < i+1且array[k] < array[i+1] } ∪ {1} 中的最大值即为LIS[i+1]。
后面便可以用动态规划的方法求解数组LIS[ ],而LIS[ ]中的最大元素即为数组中最长递增子序列的长度。

代码清单:

int lis(int arr[],int n)
{
	int *lis;
	int i,j,max = 0;
	lis = (int*)malloc(sizeof(int) * n);
	
	for(i = 0;i < n;i++)
		lis[i] = 1;
	for(i = 1;i < n;i++)
		for(j = 0;j < i;j++)
			if(arr[i] > arr[j] && lis[i] < lis[j] + 1)
				lis[i] = lis[j] + 1;

	for (i = 0;i < n;i++) //max(lis)
		if(max < lis[i])
			max = lis[i];
	free(lis);
	return max;
}
int main()
{
	int arr[] = {1,-1,2,-3,4,-5,6,-7};
	cout<<"length of LIS is "<<lis(arr,sizeof(arr)/sizeof(arr[0]))<<endl;
	getchar();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值