감사쟁이야
감사쟁이의 성장기록
감사쟁이야
  • 분류 전체보기 (130)
    • Java-Spring (0)
    • ComputerScience (0)
    • Project (64)
      • TIL, WIL (57)
      • Project Retrospect (7)
    • Problem Solving (63)
    • Book Review (1)
    • Culture & Discovery (0)
    • Daily Log (2)

블로그 메뉴

  • 홈
  • 깃허브
  • 방명록
hELLO · Designed By 정상우.
감사쟁이야

감사쟁이의 성장기록

[백준] 1182 : 부분 수열의 합 / python
Problem Solving

[백준] 1182 : 부분 수열의 합 / python

2022. 2. 27. 14:30

1. 문제 설명

 

1182번: 부분수열의 합

첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, |S| ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.

www.acmicpc.net

N개의 정수로 이루어진 수열이 있을 때,

크기가 양수인 부분수열 중에서 그 수열의 원소를 다 더한 값이 S가 되는 경우의 수를 구하는 프로그램을 작성

입력

첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, |S| ≤ 1,000,000)

둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.

출력

첫째 줄에 합이 S가 되는 부분수열의 개수를 출력한다.

 

2. 풀이 전 계획과 생각

부분수열의 갯수를 구한다.

모든 부분 수열을 따질 경우,

시간 복잡도는 2^20 - 1 = 약 10^6

완전 탐색으로 구할 수 있다.

 

합이 S가 되는 모든 경우의 수를 다 따진다.

합이 S가 되면 count 증가시킨다.

 

3. 풀이 - 조합

from itertools import combinations

N, S = map(int, input().split())
arr = list(map(int, input().split()))
count = 0

for num in range(1, N+1):
    for case in list(combinations(arr, num)):
        if sum(case) == S:
            count += 1

print(count)

 

4. 풀이 - 재귀로도 풀어보기

⇒ 해당 원소를 순회해서 고를지 안고를지 결정한다.

 

이를 위해, 매 함수마다 해당 원소를 부분 수열에 포함할지 말지 결정하는 인덱스와

현재까지의 부분 수열의 합을 체크해줘야 한다.

⇒ go(index, sum)

 

또한 합을 찾았다고 해도 종료해주면 안된다. 뒤의 원소까지 포함한 합을 구해도 답이 되는 경우가 있다.

종료조건은 index == 배열의 size다.

⇒ 정답을 찾은 경우

  • index == N and sum == M
  • (있고 없는 경우를 다따지기 위해 재귀를 2번 호출하니 index가 N까지 가고난 뒤, count 해야 한다.)

⇒ 불가능한 경우

  • index == N and sum ≠ M

⇒ 다음 경우

  • index번째 부분수열에 추가 : go(index + 1, sum + arr[i])
  • index번째 부분수열에 추가하지 않음 : go(index + 1, sum)

 

🤔  앗! 부분 수열의 크기가 양수라는 조건이 있으니,

전체에서 모두 포함하지 않는 경우는 빼주자.

전체에서 모두 포함하지 않는 경우가 정답이 될 때는 S가 0일 때다.

 

N, S = map(int, input().split())
arr = list(map(int, input().split()))
count = 0

def go(index, sum):
    global count
    if index == N :
        if sum == S:    count += 1
        return

    go(index + 1, sum + arr[index])
    go(index + 1, sum)

go(0, 0)
if S == 0:
    count -= 1
print(count)

'Problem Solving' 카테고리의 다른 글

[백준] 2667 : 단지번호붙이기 / python  (0) 2022.03.03
[프로그래머스] 오픈채팅방 (2019 KAKAO BLIND) / python  (0) 2022.02.28
[백준] 7576 : 토마토 / python  (0) 2022.02.25
[백준] 14888 : 연산자 끼워넣기 (삼성 SW 역량 테스트) / python  (0) 2022.02.20
[백준] 14499 : 주사위 굴리기 (삼성 SW 역량 테스트) / python  (0) 2022.02.19
    'Problem Solving' 카테고리의 다른 글
    • [백준] 2667 : 단지번호붙이기 / python
    • [프로그래머스] 오픈채팅방 (2019 KAKAO BLIND) / python
    • [백준] 7576 : 토마토 / python
    • [백준] 14888 : 연산자 끼워넣기 (삼성 SW 역량 테스트) / python
    감사쟁이야
    감사쟁이야
    sunzero0116@gmail.com

    티스토리툴바