具有模数的子集和变量

时间:2017-12-19 17:18:44

标签: algorithm dynamic-programming subset-sum

给定整数A和整数N,M的数组。我想找到A的所有子集S,其中(sum(S)mod M = N)。 A可以具有相同值的多个整数。 在我的情况下,N将在0 <= n <= 31的范围内,M将是32,A将包含与n相同的整数。

有没有好/“快”的方法呢?

谢谢!

2 个答案:

答案 0 :(得分:1)

可在O(2 n / 2 log 2 (2 n / 2 ))= O(2 n / 2 (n / 2)),你的约束在C ++上的工作时间不到一秒。

您只需要:

1)计算数组中第一个n/2元素的所有可能总和,并将它们放在map<int, int> left left[sum] =数组左侧出现的次数<{1}}

2)计算数组的最后n/2个元素的所有可能总和,并且对于每个总和S,检查地图left是否包含值(N - S + M)%M

找到所有可能使用位掩码的总和:

for (int mask = 1; mask < pow(2, n/2); mask++) {
    int sum = 0;
    for (int i = 0; i < n/2; i++)
        if ( (int) (mask & (1<<i)) ) 
            sum += A[i];
}

答案 1 :(得分:0)

如果您只想计算它们,我们可以使用动态编程在O(|A| * M)中解决它。这是一个例子:

A = [2, 6, 4, 3]
M = 5

    0 1 2 3 4
S = 0 0 0 0 0 // The number of subsets with sum i (mod M)

// Iterate over A (through S each time)
2   0 0 1 0 0
6   0 1 1 1 0
4   1 2 2 1 1
3   3 3 3 3 3

Python代码:

A = [2, 6, 4, 3]
M = 5
S = [0 for i in xrange(0, M)]
STemp = [0 for i in xrange(0, M)]

for a in A:
  for (i, v) in enumerate(S):
    ii = (a + i) % M
    STemp[ii] = S[ii] + v
  STemp[a % M] = STemp[a % M] + 1
  S = STemp
  STemp = [0 for i in xrange(0,M)]

print S  # [3, 3, 3, 3, 3]