반응형
https://www.acmicpc.net/problem/9184
문제 설명
if a <= 0 or b <= 0 or c <= 0, then w(a, b, c) returns:
1
if a > 20 or b > 20 or c > 20, then w(a, b, c) returns:
w(20, 20, 20)
if a < b and b < c, then w(a, b, c) returns:
w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c)
otherwise it returns:
w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1)
이러한 재귀함수 w를 수행시간이 짧아지도록 구현하는 문제이다.
풀이 과정
문제에서 주어진 재귀함수의 수행시간이 오래걸리는 이유는 매번 값을 계산하기 때문이다.
한 번 계산된 값도 다음에 다시 계산이 된다.
그래서 매번 값을 계산하도록 하는 형식이 아닌 한 번 계산된 값은 저장하도록 하면 된다.
그래서 DP를 이용하자.
문제에서 주어진 조건문은 그대로 구현을 해주면 된다.
단지, 계산된 값만 3차원 DP배열에 저장을 해줌으로써 재 계산을 할 필요가 없도록 하면 된다.
import sys
dp = [[[0]*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 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]
while True:
a, b, c = map(int, sys.stdin.readline().rstrip().split())
if a == -1 and b == -1 and c == -1:
break
ans = w(a, b, c)
print("w(%d, %d, %d) = %d" %(a, b, c, ans))
전체 문제 & 코드는 위의 깃에 정리되어 있습니다.
팔로우 & 맞팔은 환영입니다 !
반응형
'Algorithm > DP' 카테고리의 다른 글
[백준] 1149 RGB거리 (Python 파이썬) (0) | 2021.10.08 |
---|---|
[백준] 1904 01타일 (Python 파이썬) (0) | 2021.10.08 |
[백준] 10164 격자상의 경로 (Python 파이썬) (0) | 2021.10.06 |
[백준] 9465 스티커 (Python 파이썬) (0) | 2021.10.05 |
[백준] 2133 타일 채우기 (Python 파이썬) (0) | 2021.09.14 |