大家好 请帮助解决以下算法,
假设我们有序列(负数允许)4,3,-2,13,11,1,1,8,5我需要找到 成员之间具有最大总和的子序列,但成员之间的距离应至少为原始序列中的4。 例如子序列将是(13,8)= 21
感谢您的帮助。
答案 0 :(得分:5)
修改强>
因此,您需要最大总和子序列,以便所选子序列中的任意两个元素i
和j
具有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