혼종 꼬지마루
[백준] 1208 - 부분집합의 합2 본문
이 문제는 저도 참고하고 풀었습니다
처음 접근은 크기가 40밖에 되지 않아서 정렬하고 구간으로 나누어 S가 되는 것을 카운팅 했으나
-10 3 10의 경우 S가 0일때 답은 1, 하지만 제가 푼 방법으로는 0이 나왔기에 잘못됬다는 것을 알았습니다.
이 문제를 해결하기 위해서 먼저 배열을 양쪽으로 나누어 나올 수 있는 모든 합의 경우의 수를 L, R로 나누어 저장
그리고 나서 L에서의 하나의 값과 R에서 나오는 값이 합이 S가 되는 갯수를 세어주면 됬습니다.
하지만 N = 40일 경우 각각 경우의 수가 1048575개 씩 나오기 때문에 모두 비교하기 보다는,
두개의 합이 S가 되는 시작점, S보다 커지는 시작점을 R에서 찾아서 그 위치의 차를 더해주었습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include <iostream> #include <algorithm> #define MX 42 using namespace std; long long arr[MX]; long long L[MX*MX*MX*MX], R[MX*MX*MX*MX]; int N, S, l, r; long long dab = 0; void dfs(int d, int pos, int end, long long sum, int dir) { if (pos == end) { if (dir) L[++l] = sum; else R[++r] = sum; return; } dfs(d + 1, pos + 1, end, sum, dir); dfs(d + 1, pos + 1, end, sum + arr[pos], dir); } int main(void) { cin >> N >> S; for (int i = 0; i < N; i++) cin >> arr[i]; l = r = -1; dfs(0, 0, N / 2, 0, 1); dfs(0, N / 2, N, 0, 0); sort(R, R + (r + 1)); for (int i = 0; i <= l; i++) { int t = S - L[i]; auto lb = lower_bound(R, R + (r + 1), t); auto ub = upper_bound(R, R + (r + 1), t); dab += ub - lb; } if (S == 0) dab--; cout << dab << endl; } | cs |
'Algorithms > DFS' 카테고리의 다른 글
[SWEA] 4223 - 삼성이의 트라우마 (0) | 2018.09.08 |
---|---|
[백준] 14889 - 스타트와 링크 (0) | 2018.09.07 |
[백준] 9997 - 폰트 (0) | 2018.08.31 |
[백준] 15660 - 테트로미노(2) (1) | 2018.08.28 |
[백준] 14500 - 테트로미노 (0) | 2018.08.28 |