具有最大总和加约束的最长增加子序列 - 可以跳过允许的元素数量

时间:2016-08-24 19:54:42

标签: algorithm recursion dynamic-programming

具有最大总和(http://www.geeksforgeeks.org/dynamic-programming-set-14-maximum-sum-increasing-subsequence/)的增长最长的子序列是典型的算法问题,并且在Web上存在许多解决方案。但是,我刚刚遇到了这个问题的变种,并且不知道如何解决它。

与原始问题相比,现在还给出了一个数字m,表示从连续子范围中最多可以跳过的元素数,以便找到具有最大总和的LIS。例如,使用以下数组

[1,200,300,3,4,5,6]

LIS是1,3,4,5,6,最大总和是19.但是,如果m是1,则意味着在连续的子范围内最多可以跳过一个元素,以便找到LIS。因此,上述解决方案不正确,因为在1和3之间,跳过了两个元素(在这种情况下为200,300)。新的解决方案应该是3,4,5,6,因为在连续的子范围内没有跳过任何元素。问题是找到具有最大和的LIS,并在给出数组和数m时返回子序列(不是子序列的总和或长度)。我已经坚持了几天这个问题,所以任何帮助表示赞赏。

编辑:O(n ^ 2)解决方案目前还不错,因为我完全不知道从哪里开始。

编辑:m是整个数组可以跳过的累积步骤,而不是两个单独的增加子序列之间可以跳过的步骤。

1 个答案:

答案 0 :(得分:1)

使用动态编程技术可以解决这个问题。

调用输入数组data length n

假设我们有一个数组dp[n][n + 1],条目dp[i][j]存储最近的索引,从idp[i][j],增加的子序列的起始长度为{{ 1}}是i。如果我们有j,那么您的问题的结果就是直接前进。

现在,如何计算特定dp的{​​{1}}?将dp[i][j]从索引j向后移动到i,假设我们维护另一个数组n - 1,其中0存储所有索引list[n + 1],其中在list[i]和长度k处开始增加子序列。我们需要维护k的属性:i正在递减列表,其中元素位于list[j],而list[j]位于xy当且仅当list[j]。如果我们对data[x] > data[y]的每个长度x < y list[j]j,我们只需要在dp[i][j + 1]内进行二分搜索,找到列表[j]中的最大元素,大于数据[i]中。

list[j]

时间复杂度 O(n ^ 2 logn)