여름의 서재

[백준] 1208_부분수열의 합 2 본문

알고리즘/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)

 

 

'알고리즘 > BOJ' 카테고리의 다른 글

[백준] 2116_주사위 쌓기  (0) 2021.08.18
[백준] 2628_종이자르기  (0) 2021.08.18
[백준] 2805_나무 자르기  (0) 2021.08.13
[백준] 1244_스위치 켜고 끄기  (0) 2021.08.13
[백준] 14647_준오는 조류혐오야!!  (0) 2021.08.13
Comments