具有最大总和(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是整个数组可以跳过的累积步骤,而不是两个单独的增加子序列之间可以跳过的步骤。
答案 0 :(得分:1)
使用动态编程技术可以解决这个问题。
调用输入数组data
length n
。
假设我们有一个数组dp[n][n + 1]
,条目dp[i][j]
存储最近的索引,从i
到dp[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]
位于x
,y
当且仅当list[j]
。如果我们对data[x] > data[y]
的每个长度x < y
list[j]
,j
,我们只需要在dp[i][j + 1]
内进行二分搜索,找到列表[j]中的最大元素,大于数据[i]中。
list[j]
时间复杂度 O(n ^ 2 logn)。