问题描述:
写一个时间复杂度尽可能低的程序,求一个一维数组(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();
}