정수 A와 정수 N, M의 배열이 주어 졌을 때, A의 모든 부분 집합 S를 찾고 싶습니다. (sum (S) mod M = N). A는 같은 값의 정수를 가질 수 있습니다. 내 경우에 N은 0 범위에있을 것입니다. < = n < = 31, M은 32가 될 것이고 A는 n과 같은 범위의 정수를 포함하게됩니다.모듈로를 가진 부분 합계 변형
이렇게하려면 "빠른"방법이 있습니까?
감사합니다.
정수 A와 정수 N, M의 배열이 주어 졌을 때, A의 모든 부분 집합 S를 찾고 싶습니다. (sum (S) mod M = N). A는 같은 값의 정수를 가질 수 있습니다. 내 경우에 N은 0 범위에있을 것입니다. < = n < = 31, M은 32가 될 것이고 A는 n과 같은 범위의 정수를 포함하게됩니다.모듈로를 가진 부분 합계 변형
이렇게하려면 "빠른"방법이 있습니까?
감사합니다.
이 O에서 풀수 (2 N/2 로그 (2 N/2)) = O (2 N/2 (N/2)), 당신의 제약을 가진이 작품 C++에서 초 미만.
당신이 필요로하는 모든
은 다음과 같습니다1) 배열의 첫번째 n/2
요소의 모든 가능한 금액을 계산하고 map<int, int> left
에 넣어 어디 left[sum] =
합은 배열의 왼쪽에 나타납니다 몇 번
2) 배열의 마지막 n/2
요소의 모든 가능한 금액을 계산하고 각 합 S
검사의 경우와지도 left
는 값을 포함 (N - S + M)%M
가능한 모든 합계는 bitmas을 사용할 수를 찾을 수 ks :
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];
}
계산하려는 경우 동적 프로그래밍을 사용하여 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
파이썬 코드 :
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]
안녕하세요! 나는 표적 합 (N)이 어디에서오고 있는지 정말로 모른다. 또한 당신이 만든 테이블에 대해 설명해 주실 수 있으며, 그것이 말하는 것과 당신이 읽을 수있는 것을 실제로 얻지 마십시오. 감사! –
@AntonAndell 그것을 확인해 주셔서 감사합니다. 이것은 'i'가'0'에서'M-1'까지의 범위에있는'i'''''''' M을 합한 부분 집합의 수를 계산하는 해법입니다. 따라서 M을 합친 합이 N 인 부분 집합의 수는 최종 배열에 포함됩니다. 테이블은 실제로'A'에서 다음 요소를 처리 할 때 갱신되는 한 행입니다. –
@AntonAndell 행의 각 인덱스는 앞에서 설명한 것처럼 "인덱스 인덱스'(mod'M')가있는 부분 집합의 수를 나타냅니다." 이전 행에 다음 요소를 적용 할 수있는 방법을 생각해 볼 수 있습니까? 도움이 필요하면 알려주세요. 여기에 힌트가 있습니다. "S [i]로 표현 된 각 하위 집합에 대해 다음 요소로 생성 될 수있는 하위 집합의 수는 'A'의 'a'이고 그 개수는 어디에 배치됩니까? 우리가 어떤 부분 집합에'a'를 추가한다면, 우리는 그 결과 mod'M'을 알 것입니다. –
일부 코드와 벤치 마크를 작성합니다. – jdv