给定整数A和整数N,M的数组。我想找到A的所有子集S,其中(sum(S)mod M = N)。 A可以具有相同值的多个整数。 在我的情况下,N将在0 <= n <= 31的范围内,M将是32,A将包含与n相同的整数。
有没有好/“快”的方法呢?
谢谢!
答案 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]