部分和的可分性和整数的差异

时间:2015-06-29 10:11:27

标签: algorithm time-complexity

问题在于:

给定一组整数k > 1和另一个整数A,是否可以将x分成两个子集,其总和分别为y(x - y) mod k = 0 ,其中O(2^N)

很明显,通过列出所有可能的分区,存在时间复杂度count算法,但是有更高效的分区吗?或者这相当于subset sum problem

1 个答案:

答案 0 :(得分:3)

这实际上相当于子集和,并且可以使用DP解决方案有效地解决(伪多项式时间),因为您的数字是整数。

一个简单的解决方案是使用子集sum的动态规划解决方案:

D(0,i) = true     i >= 0
D(x,0) = false    x != 0
D(x,i) = D(x-arr[i],i-1) OR D(x,i-1)

通过构建DP表(自下而上的解决方案),完成后您需要做的就是检查是否有x这样:

D(x,n) = true, abs(x-(SUM-x)) % k = 0
Where:
n - number of elements
SUM = arr[1] + arr[2] + ... + arr[n]
k - the given integer for mod
(x-y) % k = (x-(SUM-x)) % k

但是,对于较小的k值,您可以将其优化为O(n*k)(而非O(n*SUM)。这仍然是伪多项式时间,但如果{{ {1}}。

首先请注意k << SUM,并且您正在寻找一个总和为x-y = x-(SUM-x) = 2x-SUM的子集,以便x

一个简单的优化是仅对大小2x - SUM % k = 0执行DP表,如下所示:

(k+1) * (n+1)

上述情况属实,因为D(0,i) = true i >= 0 D(x,0) = false x != 0 D(x,i) = D((x-arr[i])%k,i-1) OR D(x,i-1) (其中负数的%k被定义为complementary modulus

现在,当您完成设置表格后,您可以搜索是否有(a-b)%k = (a%k - b%k)%k x。这是有效的,因为对于总和为((2x)%k - SUM%k) %k == 0的每个子集:

t