티스토리 뷰
다이나믹 프로그래밍
- 메모리를 적절히 사용하여 수행 시간 효율성을 비약적으로 향상시키는 방법
- 이미 계산된 결과는 메모리에 저장하여 다시 계산하지 않도록 한다.
- DP의 구현은 탑다운(위에서 아래로), 보텀업(아래서 위로)으로 구성된다.
- 동적 계획법이라고도 한다.
- 최적 부분 구조: 큰 문제를 작은 문제로 나눌 수 있으며 작은 문제의 답을 모아 큰 문제를 해결할 수 있다.
- 중복되는 부분 문제: 동일한 작은 문제를 반복적으로 해결해야 한다.
DP 대표문제 (피보나치 수열)
1 1 2 3 5 8 13 21 34 55 ...
이 수열에서 알아낸 항들 사이의 관계식을 점화식이라고 한다.
계산되는 과정을 나타내는 표를 배열이나 리스트로 표현할 수 있다.
점화식으로 표현될 수 있는 구조는 재귀함수를 이용해 프로그램 상에 구현할 수 있다.
def fibo(x):
if x == 1 or x ==2: # 재귀함수 종료 조건
return 1
return fibo(x-1) + fibo(x-2)
print(fibo(4)) # 결과: 3
하지만 중복되는 부분이 많아 지수 시간 복잡도를 가지게 된다.
이 문제는 다이나믹 프로그래밍으로 해결할 수 있다. (위의 두 조건이 맞을 경우)
메모이제이션(memoization)
: 한 번 계산한 결과를 메모리 공간에 메모하는 기법이다.
- 같은 문제를 다시 호출하면 메모했던 결과를 그대로 가져온다.
- 값을 기록해 놓는다는 점에서 캐싱(caching)이라고도 한다. (→ 변수명: dp, d, cach, memo)
탑다운 방식(메모이제이션)은 하향식이라고도 하고, 보텀업 방식은 상향식이라고도 한다.
다이나믹 프로그래밍의 전형적 형태는 보텀업 방식이다.
메모이제이션은 다이나믹 프로그래밍에 국한된 개념이 아니라, 계산 결과를 일시적으로 기록해놓는 개념을 의미한다.
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])
다이나믹 프로그래밍 vs 분할 정복
다이나믹 프로그래밍 | 분할 정복 (퀵 정렬) | |
공통점 | 최적 부분 구조를 가질 때 사용 가능 (큰 문제를 작은 문제로 나누고, 작은 문제를 모아 큰 문제를 해결할 수 있음) | |
차이점 | 각 부분 문제들이 서로 영향을 미치며 부분 문제가 중복됨 | 동일 부분 문제가 반복적으로 계산 되지 않음 |
문제 접근 방법
- DP 유형임을 파악하는 것이 중요
- 그리디, 구현, 완전 탐색으로 풀 수 있는지 먼저 검토
- 재귀 함수로 비효율적인 완전 탐색을 한 후에 작은 문제에서 구한 답이 큰 문제에서 사용될 수 있으면 탑다운 방식으로 풀어본다.
'Python > 이코테' 카테고리의 다른 글
8-4. 바닥 공사 (0) | 2022.07.15 |
---|---|
8-3. 개미 전사 (0) | 2022.07.15 |
8-2. 1로 만들기 (0) | 2022.07.10 |
7-1. 범위를 반 씩 줄여가는 탐색 (0) | 2022.07.10 |
7-3. 떡볶이 떡 만들기 (0) | 2022.07.08 |
댓글