最大化N个正数中K个不相交和连续的大小为L的子集的总和

时间:2015-03-25 23:27:12

标签: algorithm dynamic-programming subset np-hard

我试图找到一种算法来查找实数的数组K的大小为L的{​​{1}}个不相交的连续子集,这些子集最大化了元素的总和。

详细说明,X是一组N个正实数:
    x

一个名为X={x[1],x[2],...x[N]} where x[j]>=0 for all j=1,...,N.的长度为L的连续子集被定义为X的L个连续成员,从位置S[i]开始到结束位置n[i]
n[i]+L-1

如果S[i] = {x[j] | j=n[i],n[i]+1,...,n[i]+L-1} = {x[n[i]],x[n[i]+1],...,x[n[i]+L-1]}.,则其中两个此类子集S[i]S[j]称为成对不相交(非重叠)。换句话说,他们不包含任何相同的X成员。

定义每个子集成员的总和:

|n[i]-n[j]|>=L

目标是找到长度为L的K个连续且不相交(非重叠)的子集SUM[i] = x[n[i]]+x[n[i]+1]+...+x[n[i]+L-1]; ,以使S[1],S[2],...,S[K]最大化。

1 个答案:

答案 0 :(得分:2)

这是通过动态编程解决的。让M[i]成为i的第一个x元素的最佳解决方案。然后:

M[i] = 0 for i < L
M[i] = max(M[i-1], M[i-L] + sum(x[i-L+1] + x[i-L+2] + ... + x[i]))

问题的解决方案是M[N]

编码时,您可以递增计算总和(或简单地预先计算所有总和),从而在空间和时间上导致O(N)解决方案。

如果您必须准确找到K个子集,则可以通过将M[i, k]定义为第一个k元素上i个子集的最佳解决方案来扩展此范围。然后:

M[i, k] = 0 for i < k * L or k = 0.
M[i, k] = max(M[i-1, k], M[i-L, k-1] + sum(x[i-L+1] + ... + x[i])

问题的解决方案是M[N, K]

这是一个2d动态编程解决方案,具有O(NK)的时间和空间复杂度(假设您使用与上面相同的技巧来避免重新计算总和)。