-
[Python]백준 9184/신나는 함수 실행/dp정리/top-downalgorithm/문제 2022. 3. 10. 19:04반응형
https://www.acmicpc.net/problem/9184
⚡️ 문제 설명
다음과 같은 재귀함수 w(a, b, c)가 있다.
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)
위의 함수를 구현하는 것은 매우 쉽다. 하지만, 그대로 구현하면 값을 구하는데 매우 오랜 시간이 걸린다. (예를 들면, a=15, b=15, c=15)
a, b, c가 주어졌을 때, w(a, b, c)를 출력하는 프로그램을 작성하시오.
⚡️ 해결 방법
예시로는 피보나치 수열이 있다.
단순 재귀
def fibo(x): if x==1 or x==2: return 1 return fibo(x-1)+fibo(x-2)
이는 문제에서 재시한 단순 재귀 호출 방식이다. 단순 재귀 함수는 지수 시간 복잡도를 가진다.
하향식 (top-down) - 재귀 함수
d=[0]*100 def fibo(x): # 종료 조건 if x==1 or x==2: return 1 # 이미 계산했다면 그대로 반환 if d[x]!=0: return d[x] d[x]=fibo(x-1)+fibo(x-2) return d[x]
하향식 방식은 한번 계산한 결과를 메모리 공간에 메모하는 기법이다. 같은 문제를 다시 호출하면 메모했던 결과를 그대로 다시가져온다.
상향식 (bottom up) - 반복문
d=[0]*100 d[1]=1 d[2]=1 for i in range(3,n+1): d[i]=d[i-1]+d[i-2]
전형적인 dp 형태는 위와 같이 보텀업 방식이다.
이문제를 해결하기 위하여 top down 방식을 이용했다.
⚡️ 코드
import sys input = sys.stdin.readline d = [[[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(d[a][b][c] !=0 ): return d[a][b][c] elif a < b < c: d[a][b][c] = w(a, b, c - 1) + w(a, b - 1, c - 1) - w(a, b - 1, c) else: d[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 d[a][b][c] while True: a, b, c = map(int, input().split()) if (a == -1 and b == -1 and c == -1): break print("w(%d, %d, %d) = %d" % (a, b, c, w(a, b, c)))
반응형'algorithm > 문제' 카테고리의 다른 글
[Python]백준 14502/연구소 / 조합 / 배열 복사 copy (0) 2022.03.12 [Python]백준 15649/N과 M(1)(2)(3)(4) / itertools (0) 2022.03.12 [Python]백준 1309/동물원/dp (0) 2022.03.03 [Python]백준 2579/계단오르기/dp (0) 2022.03.03 [Python]백준 2644/촌수계산/dfs/bfs (0) 2022.02.27