13강 / 20강
동적 계획법 — 한 번 계산한 건 다시 계산하지 않는다
메모이제이션 = 알고리즘 안의 캐시
12강에서 완전 탐색이 2ⁿ으로 폭발하는 걸 봤습니다. 그런데 그 폭발의 상당 부분은 같은 계산을 반복하는 데서 옵니다.
계산한 결과를 적어 두었다가 다시 쓰면 어떨까요? 이 단순한 아이디어가 동적 계획법(Dynamic Programming, DP)입니다.
이름은 무섭지만, 핵심은 이 한 문장이에요.
이미 푼 문제는 다시 풀지 않는다.
n=30에 이미 130만 번. n=50이면 200억 번입니다.
Python
브라우저에서 실행
왜 이렇게 폭발할까요
피보(5)를 계산하려면 피보(4)와 피보(3)이 필요합니다.
그런데 피보(4)도 피보(3)을 필요로 해요.
같은 값을 몇 번이고 다시 계산합니다.
계산한 걸 메모해 두면 두 번째부터는 그냥 꺼내 쓰면 됩니다. 이것을 메모이제이션(memoization)이라고 해요.
딕셔너리 한 줄이 O(2ⁿ)를 O(n)으로 만듭니다.
Python
브라우저에서 실행
🎮 메모이제이션 실험실
메모를 켜고 끄면서 호출 횟수를 비교해 보세요. 호출 트리가 그려지는데, 메모를 켜면 가지가 잘려 나가는 모습이 보입니다. n을 조금씩 올려 보면 폭발이 얼마나 무서운지 실감할 수 있어요.
쇼핑몰에서의 DP — 배송비 최소화
실전 문제입니다. 창고가 여러 곳에 있고, 주문을 어느 창고에서 보낼지에 따라 배송비가 달라집니다. 게다가 합배송 할인도 있어요.
모든 조합을 다 해 보면 지수 시간이지만, "i번째 상품까지 처리했을 때의 최소 비용"을 저장해 두면 선형에 가까워집니다.
표 하나를 채워 나가는 것 — 이것이 DP의 전형적인 모습입니다.
Python
브라우저에서 실행
탐욕 vs DP vs 완전 탐색 — 정리
| 속도 | 정확도 | 언제 쓰나 | |
|---|---|---|---|
| 탐욕 | 가장 빠름 O(n log n) | 보장 안 됨 | 구조가 받쳐 줄 때 · 빠른 근사가 필요할 때 |
| DP | 보통 O(n×m) | ✅ 최적 보장 | 부분 문제가 겹칠 때 |
| 완전 탐색 | 가장 느림 O(2ⁿ) | ✅ 최적 보장 | n이 아주 작을 때 · 정답 검증용 |
실무 순서는 이렇습니다. ① 완전 탐색으로 정답을 구해 두고 → ② 빠른 알고리즘을 만든 뒤 → ③ 둘의 답을 비교해 검증. 12강 위젯에서 한 것이 바로 이 검증이었어요.
🤔 확인 문제
메모이제이션(memoization)의 핵심 아이디어는?
해설 같은 계산을 두 번 하지 않는다가 전부입니다. 16강의 캐시와 정확히 같은 아이디어예요.
🤔 확인 문제
메모 없는 재귀 피보나치의 시간 복잡도는?
해설 매 호출이 두 번씩 갈라지므로 지수 시간 O(2ⁿ)입니다. 메모를 붙이면 각 n을 한 번씩만 계산하니 O(n)이 돼요.
🤔 확인 문제
DP를 적용할 수 있으려면 문제가 가져야 할 성질은?
해설 겹치는 부분 문제 + 최적 부분 구조. 이 둘이 DP의 전제 조건입니다.