[백준 / 9184] 신나는 함수 실행
in Problem Solving on BaekJoon
날짜: 2022년 12월 26일
카테고리: 다이나믹 프로그래밍
태그: silver.2
, 9184
, 파이썬
입출력 예시
예제 입력 | 예제 출력 |
---|---|
1 1 1 | w(1, 1, 1) = 2 |
2 2 2 | w(2, 2, 2) = 4 |
10 4 6 | w(10, 4, 6) = 523 |
50 50 50 | w(50, 50, 50) = 1048576 |
-1 7 18 | w(-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에 대해 좀 더 이해할 수 있었던 문제
- 메모지에이션 활용의 적절한 예시를 알 수 있는 문제