CodingTest/BeakJoon
[1182] 부분수열의 합
the.Dev.Cat
2026. 3. 31. 16:57
백준 Silver II | 1182 | Python | 문제 링크
문제 설명
N개의 정수로 이루어진 수열이 있을 때, 크기가 양수인 부분수열 중에서 그 수열의 원소를 다 더한 값이 S가 되는 경우의 수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, |S| ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.
출력
첫째 줄에 합이 S가 되는 부분수열의 개수를 출력한다.
입출력 예
| 입력 | 출력 |
|---|---|
| 5 0 -7 -3 -2 5 8 |
1 |
나의 풀이
풀이 1
import sys
input = sys.stdin.readline
def backtrack(idx, total):
global count
if idx == n:
if total == s:
count += 1
return
backtrack(idx + 1, total + nums[idx])
backtrack(idx + 1, total)
n, s = map(int, input().split())
nums = list(map(int, input().split()))
count = 0
backtrack(0, 0)
if s == 0:
count -= 1
print(count)
풀이 설명
각 원소를 포함하거나 제외하는 두 갈래로 재귀를 진행한다. 모든 원소를 결정하면 합이 S인지 확인한다.
backtrack(idx + 1, total + nums[idx])— 현재 원소 포함backtrack(idx + 1, total)— 현재 원소 제외if s == 0: count -= 1— S가 0이면 빈 부분수열(합 = 0)도 카운트되므로 1을 뺀다.
풀이 2
import sys
input = sys.stdin.readline
n, s = map(int, input().split())
nums = list(map(int, input().split()))
count = 0
for mask in range(1, 1 << n):
total = sum(nums[i] for i in range(n) if mask & (1 << i))
if total == s:
count += 1
print(count)
풀이 설명
N개의 원소는 각각 포함/제외 두 가지 상태를 가지므로 부분수열의 총 경우는 2N가지다. 비트마스크로 각 경우를 표현한다.
mask의 i번째 비트가 1이면nums[i]를 포함한다는 의미다.range(1, 1 << n)— 0(빈 집합)을 제외하고 시작하므로 S == 0 보정이 필요 없다.