最大连续子序列

时间:2010-12-30 17:52:32

标签: algorithm

大家好 请帮助解决以下算法,

假设我们有序列(负数允许)4,3,-2,13,11,1,1,8,5我需要找到 成员之间具有最大总和的子序列,但成员之间的距离应至少为原始序列中的4。 例如子序列将是(13,8)= 21

感谢您的帮助。

2 个答案:

答案 0 :(得分:5)

修改

因此,您需要最大总和子序列,以便所选子序列中的任意两个元素ij具有j - i >= 4。我们可以通过动态编程解决这个问题。

a成为给定的数组。

m[i] = maximum sum subsequence with the desired properties ending at position i

如果我们有

    1  2   3   4   5  6  7  8  9  
a = 4, 3, -2, 13, 11, 1, 1, 8, 5

然后

m[1] = 4 
m[2] = 3
m[3] = -2
m[4] = 13
m[5] = max(m[5 - 4 = 1] + 11, 11) = max(4 + 11, 11) = 15
...

一般来说,我们有m[i] = max{max(m[j] + a[i], a[i]), j = 1 to i - 4}

这将是O(n^2)。您可以很容易地从中获得O(n)解决方案。请注意,在上述重复中选择最大m[j]总是有帮助的。因此,在遍历它时计算m的最大值,如下面的伪代码:

maxm = -inf
for i = 1 to a.Length do
    m[i] = a[i]

    if (i >= 4 + 1)
        if (m[i - 4] > maxm)
            maxm = m[i - 4]

        m[i] = max(m[i], maxm + a[i])


output the maximum value in `m`.

您可以轻松将其概括为k而不是4


这不是你想要的,但我还是会离开它,因为我觉得这是一个经典问题的有趣变化

如果您确实在寻找长度至少为k的最大和子序列,那么此算法将解决O(n)中的问题:

a成为您的数字数组。 让s[i] = s[i - 1] + a[i]。这称为前缀和数组。我们可以使用它来查找任何序列[i, j]的总和,如下所示:sum[i, j] = s[j] - s[i - 1]

因此,对于每个i >= k,我们需要j <= i - k + 1,以使s[j - 1]最小。拿最后给出最大金额的那个。

s[0] = 0
for i = 1 to a.Length do
    s[i] = s[i - 1] + a[i]

max = -inf
min = inf

for i = k to a.Length do
    if (s[i - k] < min)
        min = s[i - k]
    if (s[i] - min > max)
        max = s[i] - min

答案 1 :(得分:2)

如果没有“至少k个元素”部分,这是一个经典问题:www.codemanic.com/mathnotes/papers/maxsum/MaxSum.pdf