출시·고도화 중
Algorithm
동적 계획법(DP)은 겹치는 부분 문제의 답을 저장해 다시 쓰는 기법으로, 지수 시간이 걸리는 탐색을 표 채우기로 바꿔 최적화와 경우의 수 문제를 풉니다.
동적 계획법(Dynamic Programming, DP)은 큰 문제를 작은 부분 문제로 나누고, 각 부분 문제를 한 번만 풀어 답을 저장한 뒤 같은 부분 문제가 다시 나오면 저장한 답을 꺼내 쓰는 알고리즘 설계 기법입니다. 1950년대 리처드 벨먼이 정리했으며, 부분 문제가 서로 겹치고(overlapping subproblems) 전체 최적 해가 부분 문제의 최적 해로 이루어질 때(optimal substructure) 쓸 수 있습니다.
단순한 재귀나 완전 탐색으로는 지수 시간이 걸리는 문제도 DP를 쓰면 상태 수에 비례하는 시간 안에 풀 수 있습니다. 파일 비교 도구의 diff, 맞춤법 검사의 편집 거리, DNA 서열 정렬, 음성 인식의 비터비 알고리즘, 데이터베이스의 조인 순서 결정 등 실제 시스템 곳곳에 쓰이며, 코딩 테스트와 기술 면접에서도 가장 자주 나오는 주제 가운데 하나입니다.
공부할 때는 피보나치로 메모이제이션(하향식)과 타뷸레이션(상향식)의 차이를 먼저 익히고, 동전 교환, 0/1 배낭, 최장 증가 부분 수열(LIS), 최장 공통 부분 수열(LCS), 편집 거리 같은 고전 문제를 차례로 풀어 보는 것이 좋습니다. 문제마다 상태, 점화식, 기저 사례, 계산 순서를 먼저 적고, 작은 표를 손으로 채워 점화식을 확인한 다음 코드로 옮기는 습관을 들이면 새로운 문제에도 응용할 수 있습니다.
같은 부분 문제가 여러 번 나올 때 한 번만 계산하고 저장해 두어, 반복 계산을 표 조회로 바꿉니다.
전체 문제의 최적 해를 부분 문제의 최적 해로 조립할 수 있어야 하며, 이 성질이 점화식의 근거가 됩니다.
재귀에 캐시를 붙이는 하향식(functools.cache)과 반복문으로 표를 채우는 상향식 두 가지로 구현합니다.
답을 결정하는 최소한의 매개변수로 상태를 정하고, 이전 행만 필요하면 롤링 배열로 메모리를 줄입니다.
knapsack은 0/1 배낭 문제를 한 행짜리 표로 푸는 상향식 구현으로, 용량을 큰 쪽부터 돌아 물건마다 한 번만 담기게 합니다. lcs는 두 문자열의 최장 공통 부분 수열 길이를 functools.cache로 메모이제이션한 하향식 구현입니다. python dynamic_programming.py로 실행하면 9와 4가 출력됩니다.
dynamic_programming.py
from functools import cache
def knapsack(weights, values, capacity):
"""0/1 knapsack: best total value within capacity (bottom-up, one row)."""
best = [0] * (capacity + 1)
for w, v in zip(weights, values):
for c in range(capacity, w - 1, -1): # high to low: each item used at most once
best[c] = max(best[c], best[c - w] + v)
return best[capacity]
def lcs(a, b):
"""Length of the longest common subsequence (top-down, memoized)."""
@cache
def solve(i, j):
if i == len(a) or j == len(b):
return 0
if a[i] == b[j]:
return 1 + solve(i + 1, j + 1)
return max(solve(i + 1, j), solve(i, j + 1))
return solve(0, 0)
print(knapsack([1, 3, 4, 5], [1, 4, 5, 7], 7)) # 9
print(lcs("ABCBDAB", "BDCABA")) # 4
python dynamic_programming.py설치부터 동적 계획법 의 핵심 개념까지, 여섯 장으로 차근차근 따라 합니다.
동적 계획법 에 관해 묻고, 경험을 나누고, 의견을 주고받는 곳입니다.
아직 토론이 없습니다. 첫 이야기를 시작해 보세요.
댓글 0개
로그인 · 로그인하면 댓글을 남길 수 있습니다.
첫 댓글을 남겨 보세요.