[백준 / 9184] 신나는 함수 실행


날짜: 2022년 12월 26일
카테고리: 다이나믹 프로그래밍
태그: silver.2, 9184, 파이썬

백준 9184 - 신나는 함수 실행

입출력 예시

예제 입력예제 출력
1 1 1w(1, 1, 1) = 2
2 2 2w(2, 2, 2) = 4
10 4 6w(10, 4, 6) = 523
50 50 50w(50, 50, 50) = 1048576
-1 7 18w(-1, 7, 18) = 1
-1 -1 -1 

내가 적은 코드

def w(a,b,c):
    if a <= 0 or b <= 0 or c <= 0:
        return 1
    if a > 20 or b > 20 or c > 20:
        return w(20, 20, 20)
    if dp[a][b][c]:
        return dp[a][b][c]
    if a < b < c:
        dp[a][b][c] = w(a,b,c-1)+w(a,b-1,c-1)-w(a, b-1, c)
        return dp[a][b][c]
    dp[a][b][c] = w(a-1, b, c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1)
    return dp[a][b][c]

dp = [[[0]*(21) for _ in range(21)] for _ in range(21)]

while True:
    a, b, c = map(int, input().split())
    if a == -1 and b == -1 and c == -1:
        break
    print('w({}, {}, {}) = {}'.format(a, b, c, w(a,b,c)))

풀이 과정

기존 제시된 로직을 그대로 가져다가 붙이면 당연하지만 시간초과가 난다.
DP의 메모지에이션 방식을 활용해 DP 배열을 만든 뒤 복잡도를 최소화하게 되면 주어진 시간 내 풀이가 가능해진다.

베스트 코드

import sys
input = sys.stdin.readline

s = [[[0 for _ in range(21)] for _ in range(21)] for _ in range(21)]

def w(a,b,c):
    if a<=0 or b<=0 or c<=0:
        return 1
    if a>20 or b>20 or c>20:
        return w(20,20,20)
    if s[a][b][c]:
        return s[a][b][c]
    elif a < b < c:
        s[a][b][c] = w(a, b, c-1) + w(a, b-1, c-1) -w(a, b-1, c)
    else: 
        s[a][b][c] = w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1)
    return s[a][b][c]
  
while True:
    a, b, c = map(int, input().split())
    if a == -1 and b == -1 and c == -1:
        break
    print(f"w({a}, {b}, {c}) = {w(a,b,c)}")

리뷰

  • 쉬운 문제여서 오히려 DP에 대해 좀 더 이해할 수 있었던 문제
  • 메모지에이션 활용의 적절한 예시를 알 수 있는 문제




© 2021. by hminkim