"매 overlapping subproblem 의 cache 의 의 의 exponential → polynomial". 매 1953 Bellman 의 명명 ("dynamic" 의 RAND 의 selling reason). 매 modern algo 의 universal tool — 매 Bioinformatics, ML training, RL value iteration 의 base.
매 핵심
매 두 조건 (DP applicability)
Optimal substructure: 매 optimal solution 의 sub-optimal solution 의 의 build.
Overlapping subproblems: 매 same subproblem 의 repeatedly 의 solve.
매 두 style
Top-down (memoization): recursion + cache. 매 declarative, lazy.
Bottom-up (tabulation): iterative table fill. 매 stack-safe, faster constant.
매 state design
state: 매 minimal info 의 의 의 subproblem 의 identify.
defknapsack(weights:list[int],values:list[int],capacity:int)->int:n=len(weights)dp=[[0]*(capacity+1)for_inrange(n+1)]foriinrange(1,n+1):forwinrange(capacity+1):ifweights[i-1]<=w:dp[i][w]=max(dp[i-1][w],dp[i-1][w-weights[i-1]]+values[i-1])else:dp[i][w]=dp[i-1][w]returndp[n][capacity]# Time O(n·W), Space O(n·W) — can compress to O(W) with reverse iteration
deftsp(dist:list[list[int]])->int:n=len(dist)INF=float('inf')dp=[[INF]*nfor_inrange(1<<n)]dp[1][0]=0# start at 0 with mask {0}formaskinrange(1,1<<n):foruinrange(n):ifnot(mask&(1<<u))ordp[mask][u]==INF:continueforvinrange(n):ifmask&(1<<v):continuenew_mask=mask|(1<<v)dp[new_mask][v]=min(dp[new_mask][v],dp[mask][u]+dist[u][v])returnmin(dp[(1<<n)-1][u]+dist[u][0]foruinrange(1,n))# O(n²·2ⁿ) — feasible for n ≤ 20
매 결정 기준
상황
Approach
매 overlapping subproblem 의 detect
DP
매 unique subproblem (no overlap)
divide & conquer
매 greedy 의 optimal proof 가능
greedy (faster, less memory)
매 state 의 huge
approximate DP / RL
매 small recursion depth
top-down (cleaner)
매 deep recursion 의 우려
bottom-up
매 memory 의 tight
rolling array (O(prev) 의 의)
기본값: 매 first attempt 의 top-down + memo. 매 deep / huge 의 의 의 bottom-up.
언제: 매 optimization problem 의 overlapping subproblem 의 detect, 매 string/sequence problem, 매 counting problem (combinatorial), 매 RL value function 의 의.
언제 X: 매 unique subproblem (D&C 의 의), 매 greedy 의 proven optimal, 매 huge state space 의 approximation 의 의 (NN, MCTS).
❌ 안티패턴
state 의 over-include: 매 unnecessary dim 의 의 의 의 exponential blow-up.
base case X: 매 infinite recursion / wrong result.
mutable default args (Python): def f(x, memo={}) 의 cross-call leak.
bottom-up 의 wrong order: 매 state 의 dependency 의 의 의 의 의 fill 의 X.
@lru_cache with mutable args: list / dict 의 의 의 hash error — tuple 의 의.