f8b21af4be
10_Wiki/Topics 대규모 정리: - 오류 캡처/미완성 stub 문서 227개 제거 - 교차폴더 중복 43클러스터 병합 (63파일 → redirect) - 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건 - 카테고리 MOC 6개 신규 생성 - Graph 섹션 미해결 related-keyword 링크 10,058건 제거 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.9 KiB
5.9 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-dynamic-programming | Dynamic Programming | 10_Wiki/Topics | verified | self |
|
none | A | 0.95 | applied |
|
2026-05-10 | pending |
|
Dynamic Programming
매 한 줄
"매 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.
- transition: 매 state → state 의 recurrence.
- base case: 매 smallest 의 known answer.
- answer: 매 final state 의 retrieve.
매 응용
- Bioinformatics: sequence alignment (Needleman-Wunsch).
- NLP: edit distance, CKY parsing, Viterbi.
- RL: Bellman value iteration.
- Graph: Floyd-Warshall, Bellman-Ford.
- Compiler: register allocation, instruction scheduling.
💻 패턴
Fibonacci (intro example)
from functools import lru_cache
# Top-down
@lru_cache(maxsize=None)
def fib(n):
if n < 2: return n
return fib(n-1) + fib(n-2)
# Bottom-up O(1) space
def fib_bu(n):
if n < 2: return n
a, b = 0, 1
for _ in range(n - 1):
a, b = b, a + b
return b
0/1 Knapsack
def knapsack(weights: list[int], values: list[int], capacity: int) -> int:
n = len(weights)
dp = [[0] * (capacity + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for w in range(capacity + 1):
if weights[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]
return dp[n][capacity]
# Time O(n·W), Space O(n·W) — can compress to O(W) with reverse iteration
Longest Common Subsequence (LCS)
def lcs(a: str, b: str) -> int:
n, m = len(a), len(b)
dp = [[0] * (m + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for j in range(1, m + 1):
if a[i-1] == b[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
return dp[n][m]
Edit Distance (Levenshtein)
def edit_distance(a: str, b: str) -> int:
n, m = len(a), len(b)
dp = [[0] * (m + 1) for _ in range(n + 1)]
for i in range(n + 1): dp[i][0] = i
for j in range(m + 1): dp[0][j] = j
for i in range(1, n + 1):
for j in range(1, m + 1):
if a[i-1] == b[j-1]:
dp[i][j] = dp[i-1][j-1]
else:
dp[i][j] = 1 + min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])
return dp[n][m]
Coin Change (min coins)
def coin_change(coins: list[int], amount: int) -> int:
dp = [float('inf')] * (amount + 1)
dp[0] = 0
for x in range(1, amount + 1):
for c in coins:
if c <= x:
dp[x] = min(dp[x], dp[x - c] + 1)
return dp[amount] if dp[amount] != float('inf') else -1
Bitmask DP (TSP)
def tsp(dist: list[list[int]]) -> int:
n = len(dist)
INF = float('inf')
dp = [[INF] * n for _ in range(1 << n)]
dp[1][0] = 0 # start at 0 with mask {0}
for mask in range(1, 1 << n):
for u in range(n):
if not (mask & (1 << u)) or dp[mask][u] == INF: continue
for v in range(n):
if mask & (1 << v): continue
new_mask = mask | (1 << v)
dp[new_mask][v] = min(dp[new_mask][v], dp[mask][u] + dist[u][v])
return min(dp[(1 << n) - 1][u] + dist[u][0] for u in range(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.
🔗 Graph
- 부모: Optimization
- 변형: Memoization
- Adjacent: Greedy Algorithms
🤖 LLM 활용
언제: 매 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_cachewith mutable args: list / dict 의 의 의 hash error — tuple 의 의.
🧪 검증 / 중복
- Verified (Bellman 1957 "Dynamic Programming"; CLRS Ch 15; Kleinberg-Tardos Ch 6).
- 신뢰도 A.
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — DP foundations with knapsack, LCS, edit distance, bitmask TSP |