알고리즘 연습/동적 계획법 상급

[🥇5 / 백준 5557 / 파이썬] 1학년

김세진 2021. 11. 14. 15:41
반응형

 

 

5557번: 1학년

상근이가 1학년 때, 덧셈, 뺄셈을 매우 좋아했다. 상근이는 숫자가 줄 지어있는 것을 보기만 하면, 마지막 두 숫자 사이에 '='을 넣고, 나머지 숫자 사이에는 '+' 또는 '-'를 넣어 등식을 만들며 놀

www.acmicpc.net

 

문제

상근이가 1학년 때, 덧셈, 뺄셈을 매우 좋아했다. 상근이는 숫자가 줄 지어있는 것을 보기만 하면, 마지막 두 숫자 사이에 '='을 넣고, 나머지 숫자 사이에는 '+' 또는 '-'를 넣어 등식을 만들며 놀고 있다. 예를 들어, "8 3 2 4 8 7 2 4 0 8 8"에서 등식 "8+3-2-4+8-7-2-4-0+8=8"을 만들 수 있다.

상근이는 올바른 등식을 만들려고 한다. 상근이는 아직 학교에서 음수를 배우지 않았고, 20을 넘는 수는 모른다. 따라서, 왼쪽부터 계산할 때, 중간에 나오는 수가 모두 0 이상 20 이하이어야 한다. 예를 들어, "8+3+2-4-8-7+2+4+0+8=8"은 올바른 등식이지만, 8+3+2-4-8-7이 음수이기 때문에, 상근이가 만들 수 없는 등식이다.

숫자가 주어졌을 때, 상근이가 만들 수 있는 올바른 등식의 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 숫자의 개수 N이 주어진다. (3 ≤ N ≤ 100) 둘째 줄에는 0 이상 9 이하의 정수 N개가 공백으로 구분해 주어진다.

출력

첫째 줄에 상근이가 만들 수 있는 올바른 등식의 개수를 출력한다. 이 값은 263-1 이하이다.

 

예제 입력 1

11
8 3 2 4 8 7 2 4 0 8 8

예제 출력 1

10

예제 입력 2

40
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1

예제 출력 2

7069052760


 

풀이

 

처음에 문제를 보고 백트래킹인가 생각했지만, n이 3이상 100 이하로 백트래킹을 통해 경우의 수를 구한다면 약 2의 100승 정도의 연산이 필요할 것이다. 불가능하다.

따라서 dp를 통해 문제를 해결해야 한다.

 

주어진 수열을 순환하며, 현재 수까지 활용했을 때 만들 수 있는 숫자들의 경우의 수가 dp 배열에 저장된다.

본인은 슬라이딩 윈도우 방식으로 하여 메모리를 조금 더 아꼈다.

 

import sys
input = sys.stdin.readline

n = int(input())
nums = list(map(int,input().split()))
target = nums.pop()

dp = [0]*21
dp[nums[0]] = 1

for i in range(1,n-1):
    tmpDp = [0]*21
    for j in range(21):
        if dp[j] > 0:
            if j + nums[i] <= 20:
                tmpDp[j+nums[i]] += dp[j]
            if j - nums[i] >= 0:
                tmpDp[j-nums[i]] += dp[j]
    dp = tmpDp[:]
print(dp[target])
반응형