数组中最长的升序子序列(动态规划问题)
2017-11-22 12:15
218 查看
The longest Increasing Subsequence (LIS)
给定一个序列,找到这个序列的一个最长的子序列,使得子序列的所有元素是升序的,且元素之间的相对位置不变(元素可以在原数组中不相邻,但是相对位置不变)
比如, LIS for { 10, 22, 9, 33, 21, 50, 41, 60, 80 } 是 6,LIS 是 {10, 22, 33, 50, 60, 80}.
分析
arr[0…n-1]是输入,然后L(i)是到元素i为止 LIS 的长度,也就是arr[i]作为 LIS 的最后一个元素时 LIS 的长度,那么用递归形式 L(i) 可以写作:
所以这个问题可以将其分解为 subproblems 用递归进行解决:
非递归方法,这个需要开辟额外的存储空间。
wiki上边有时间复杂度为O(nlog(n))的解法
给定一个序列,找到这个序列的一个最长的子序列,使得子序列的所有元素是升序的,且元素之间的相对位置不变(元素可以在原数组中不相邻,但是相对位置不变)
比如, LIS for { 10, 22, 9, 33, 21, 50, 41, 60, 80 } 是 6,LIS 是 {10, 22, 33, 50, 60, 80}.
分析
arr[0…n-1]是输入,然后L(i)是到元素i为止 LIS 的长度,也就是arr[i]作为 LIS 的最后一个元素时 LIS 的长度,那么用递归形式 L(i) 可以写作:
for(j<i) if(arr[j]<arr[i]) L(i) = {1+Max( L(j) )} if(j == 1) //递归的终止条件 L(i) = 1
所以这个问题可以将其分解为 subproblems 用递归进行解决:
#include <iostream> using namespace std; int LIS(int *arr, int n, int *max_ref) { if(n==1) return 1; int res, longest_here=1; for(int i = 1; i<n; ++i) { res = LIS(arr, i, max_ref); if(arr[i-1]<arr[n-1] && res+1>longest_here) longest_here = res+1; } if(*max_ref < longest_here) *max_ref = longest_here; return longest_here; } int main() { int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 }; int n = sizeof(arr)/sizeof(arr[0]); int max=1; LIS( arr, n, &max); cout<<max<<endl; return 0; }
非递归方法,这个需要开辟额外的存储空间。
int LIS2(int *arr,int n) { int *longest_here = new int (); longest_here[0] = 1; int max = 1; for(int i = 1; i<n; ++i) { for(int j = 0; j<i; ++j) { if(arr[j]<arr[i] && longest_here[j]+1>longest_here[i]) longest_here[i] = longest_here[j]+1; } if(longest_here[i]>max) max = longest_here[i]; } delete []longest_here; return max; }
wiki上边有时间复杂度为O(nlog(n))的解法
相关文章推荐
- 最长上升子序列问题(动态规划)
- E - Longest Ordered Subsequence(动态规划)最长升成子序列问题
- [动态规划]最长不降子序列问题-N*N算法
- 动态规划专题小结:最长上升子序列(LIS)问题
- 算法_动态规划_最长单调递增子序列问题(O(nlogn)的时间复杂度)
- [运筹学]关于动态规划的2个问题-最长公共子序列与最长非降子序列问题
- 最长递增、递减子序列(导弹拦截问题)动态规划练习
- 动态规划----求一个数组的最长递减序列
- 矩形嵌套--动态规划--最长递增子序列问题变形
- 动态规划-数组最长递增子序列长度
- 动态规划(背包问题,最长递增子序列,硬币问题)java实现
- 递归与动态规划---数组中的最长连续序列
- 动态规划之合唱队形问题(最长递增子序列变形)
- ACM最长单调递增子序列问题(动态规划)o(n*n)C++实现
- 程序员面试金典(动态规划):叠罗汉问题_最长递增子序列(java解法)
- (2)最长不下降子序列问题____动态规划
- 动态规划--最长上升子序列问题(LIS) O(n^2) ,O(nlogn)
- hdu4521小明系列问题——小明序列 (线段树+dp,求出不连续的最长升序子序列)
- [算法导论]动态规划---最长公共最序列问题
- 数组中最长递归子序列问题研究(1)