메모리를 적절히 사용하여 수행 시간 효율성을 비약적으로 향상시키는 방법입니다.
이미 계산된 결과는 별도의 메모리 영역에 저장하여 다시 계산하지 않도록 합니다.
동적 계획법이라고도 부릅니다.
다이나믹 프로그래밍은 문제가 다음의 조건을 만족할 때 사용할 수 있습니다.
피보나치 수열은 다음과 같은 형태의 수열이며, 다이나믹 프로그래밍으로 효과적으로 계산할 수 있습니다.
1,1,2,3,5,8,13,21,34,55,89,...
피보나치 수열을 점화식으로 나타내면 다음과 같습니다.
f(n) = f(n-1) + f(n-2), f(1) = 1, f(2) = 1
n번째 피보나치 수열을 f(n)이라 할 때 f(4)를 구하는 과정은 다음과 같습니다.
def fibo(x):
if x==1 or x==2:
return 1
return fibo(x-1) + fibo(x-2)
print(fibo(4))
단순 재귀 함수로 피보나치 수열을 해결하면 지수 시간 복잡도를 가지게 됩니다.
다음과 같이 f(2)가 여러 번 호출되는 것을 확인할 수 있습니다.
피보나치 수열의 시간복잡도 : O(2^N)
메모이제이션은 한 번 계산한 결과를 메모리 공간에 메모하는 기법으로, 다이나믹 프로그래밍을 구현하는 방법 중 하나입니다.
탑다운(메모이제이션) 방식은 하향식이라고도 하며 보텀업 방식은 상향식이라고도 합니다.
다이나믹 프로그래밍의 전형적인 형태는 보텀업 방식이고, 결과 저장용 리스트는 DP 테이블이라고 부릅니다.
# 한 번 계산된 결과를 메모이제이션하기 위한 리스트
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]
print(fibo(99))
d = [0]*100
d[1] = 1
d[2] = 1
n = 99
for i in range(3,n+1):
d[i] = d[i-1] + d[i-2]
print(d[n])