最长增长子序列(LIS)问题是找到给定序列的最长子序列的长度,以使子序列的所有元素都按升序排序。例如,{10、22、9、33、21、50、41、60、80}的LIS长度为6,LIS为{10、22、33、50、60、80}。
更多示例:
Input : arr[] = {3, 10, 2, 1, 20}
Output : Length of LIS = 3
The longest increasing subsequence is 3, 10, 20
Input : arr[] = {3, 2}
Output : Length of LIS = 1
The longest increasing subsequences are {3} and {2}
Input : arr[] = {50, 3, 10, 7, 40, 80}
Output : Length of LIS = 4
The longest increasing subsequence is {3, 7, 40, 80}
最佳子结构:
令arr [0..n-1]为输入数组,令L(i)为以索引i结尾的LIS的长度,以使arr [i]为LIS的最后一个元素。
然后,L(i)可以递归写为:
L(i)= 1 + max(L(j))其中0
为了找到给定数组的LIS,我们需要返回max(L(i)),其中0 因此,我们看到LIS问题满足最佳子结构属性,因为可以使用子问题的解决方案来解决主要问题。
以下是LIS问题的简单递归实现。它遵循上面讨论的递归结构。
/* A Naive C/C++ recursive implementation of LIS problem */
#include
#include
/* To make use of recursive calls, this function must return
two things:
1) Length of LIS ending with element arr[n-1]. We use
max_ending_here for this purpose
2) Overall maximum as the LIS may end with an element
before arr[n-1] max_ref is used this purpose.
The value of LIS of full array of size n is stored in
*max_ref which is our final result */
int _lis(int arr[], int n, int* max_ref)
{
/* Base case */
if (n == 1)
return 1;
// 'max_ending_here' is length of LIS ending with arr[n-1]
int res, max_ending_here = 1;
/* Recursively get all LIS ending with arr[0], arr[1] ...
arr[n-2]. If arr[i-1] is smaller than arr[n-1], and
max ending with arr[n-1] needs to be updated, then
update it */
for (int i = 1; i < n; i++) {
res = _lis(arr, i, max_ref);
if (arr[i - 1] < arr[n - 1] && res + 1 > max_ending_here)
max_ending_here = res + 1;
}
// Compare max_ending_here with the overall max. And
// update the overall max if needed
if (*max_ref < max_ending_here)
*max_ref = max_ending_here;
// Return length of LIS ending with arr[n-1]
return max_ending_here;
}
// The wrapper function for _lis()
int lis(int arr[], int n)
{
// The max variable holds the result
int max = 1;
// The function _lis() stores its result in max
_lis(arr, n, &max);
// returns max
return max;
}
/* Driver program to test above function */
int main()
{
int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
int n = sizeof(arr) / sizeof(arr[0]);
printf("Length of lis is %d\n",
lis(arr, n));
return 0;
}
输出:
Length of lis is 5
请参考有关动态编程的完整文章。设置3(最长递增子序列)以获取更多详细信息!
想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。