문제 분류 수업 진도 대회 채점현황 순위 질문게시판
게임
스도쿠 타이핑 리듬 타자게임 타이핑 테트리스 타이핑 인베이더 타이핑 지뢰찾기 8192 공룡게임 타이핑 플래피버드 랭킹
로그인

6011 : 백트래킹 — 부분합

•시간제한: 2.000 S •메모리제한: 256 MB •제출: 0 •통과: 0 •만든사람: suakii

6011 : 백트래킹 — 부분합

시간 2.000s · 메모리 256MB · 제출 0 · 정답 0

문제 설명

$N$개의 정수가 주어질 때, 이 중 원소를 하나 이상 선택하여 그 합이 정확히 $S$가 되는 부분집합의 개수를 구하십시오.
백트래킹 탐색을 기본으로 하되, 원소 수가 $N \le 30$으로 크므로 단순 DFS 백트래킹(시간 복잡도 $O(2^{30})$)은 시간 초과가 날 수 있습니다.
정렬 후 합이 $S$를 넘어가면 탐색을 중지하거나, 전체 수들의 절반씩 나누어 부분합을 구한 뒤 병합하는 중간에서 만나기(Meet in the Middle) 기법 등을 사용해 최적화하십시오.

[제약 조건]
• 원소 개수 $N$: $1 \le N \le 20$ (정수)
• 목표 합 $S$: $1 \le S \le 10^6$ (정수)
• 각 원소: $1 \le a_i \le 10^5$ (정수)

입력 설명

첫째 줄에 정수의 개수 $N$과 목표 합 $S$가 공백으로 구분되어 주어집니다. ($1 \le N \le 30$, $1 \le S \le 10^7$)
둘째 줄에 $N$개의 정수가 공백으로 구분되어 주어집니다. (원소의 값은 $1$ 이상 $10^6$ 이하의 자연수)

출력 설명

합이 정확히 $S$가 되는 부분집합의 개수를 출력합니다. (공집합은 정답에서 제외합니다)

입력 예시
COPY
복사되었습니다!

5 5
1 2 3 4 5

출력 예시
COPY
복사되었습니다!

3

도움

수들을 절반인 $N/2$개씩 두 그룹으로 쪼갠 뒤, 각 그룹에서 만들 수 있는 모든 부분집합의 합들을 구합니다(각각 최대 $2^{15}$개). 이후 한쪽 합 $X$와 다른 쪽 합 $S-X$의 곱을 누적하는 방식을 사용하면 $O(2^{N/2})$로 해결됩니다.
NOTICE  —  BFStudy OJ 정보샘
애들아, 문제 많이 풀고 게임 잠깐 하는거지?
— 정보샘