알고리즘/BOJ
[백준] 1208_부분수열의 합 2
엉아_
2021. 8. 16. 22:56
728x90
🔑 방법
1. DFS 이용
2. 투포인터 이용
- defaultdict(default값)
: 딕셔너리와 비슷하지만 처음에 default값을 지정해줄수 있음
# 투포인터 이용
from itertools import combinations
from collections import defaultdict
N, S = map(int, input().split())
numbers = list(map(int, input().split()))
left_subset = numbers[:N//2]
right_subset = numbers[N//2:]
left_num = defaultdict(int)
right_num = defaultdict(int)
# 왼쪽 오른쪽 부분집합의 합 리스트 만들기
for i in range(N//2+1):
for subset in combinations(left_subset, i):
left_num[sum(subset)] += 1
for i in range(N-N//2+1):
for subset in combinations(right_subset, i):
right_num[sum(subset)] += 1
left_sum = sorted(left_num.keys())
right_sum = sorted(right_num.keys())
left = 0
right = len(right_sum) - 1
cnt = 0
while left < len(left_sum) and right >= 0:
if left_sum[left] + right_sum[right] == S:
cnt += left_num[left_sum[left]]*right_num[right_sum[right]]
left += 1
right -= 1
elif left_sum[left] + right_sum[right] > S:
right -= 1
else:
left += 1
if S == 0 :
cnt -= 1 # 공집합 + 공집합인 경우 빼주기 위해
print(cnt)