Dynamic Programming 문제는 3가지 유형으로 나뉜다.
1. rod cutting
2. matrix-chain multiplication
3. longest common subsequence
인치 막대를 잘라서 판매하여 얻을 수 있는 최대 수익 을 찾아라.
length | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
price | 1 | 5 | 8 | 9 | 10 | 17 | 17 | 20 | 24 | 30 |
은 로부터 구할 수 있다.
→ optimal substructure를 가졌다.
top-down
MEMOIZED-CUT-ROD(p, n)
let r[0..n] be a new array
for i = 0 to n
r[i] = -∞
return MEMOIZED-CUT-ROD-AUX(p, n, r)
MEMOIZED-CUT-ROD-AUX(p, n, r)
if r[n] >= 0
return r[n]
if n == 0
q = 0
else q = -∞
for i = 1 to n
q = max(q, p[i] + MEMOIZED-CUT-ROD-AUX(p, n-i, r))
r[n] = q
return q
bottom-up → function call이 없어서 top-down보다 효율적
BOTTOM-UP-CUT-ROD(p, n)
let r[0..n] be a new array
r[0] = 0
for j = 1 to n
q = -∞
for i = 1 to j
q = max(q, p[i] + r[j-i])
r[j] = q
return r[n]
시간 복잡도:
x…x행렬을 optimal 순서로 곱했을 때의 연산 횟수 를 구하라.
matrix | ||||||
---|---|---|---|---|---|---|
demension | 30×35 | 35×15 | 15×5 | 5×10 | 10×20 | 20×25 |
는 의 열의 개수 = 의 행의 개수 (단, 는 의 행의 개수)
따라서 의 크기는 ×
→ optimal substructure를 가지고 subproblem들이 overlap 되어있다.
MATRIX-CHAIN-ORDER(p)
n = p.length - 1
let m[1..n,1..n] be new table
for i = 1 to n
m[i,i] = 0 // 행렬이 1개일 때의 값 초기화
for l = 2 to n // chain length
for j = 1 to n-l+1
j = i+l-1
m[i,j] = ∞
for k = i to j-1
q = m[i,k] + m[k+1,j] + p_{i+1}p_{k}p_{j}
if q < m[i,k]
m[i,j] = q
return m
시간복잡도:
와 의 LCS의 길이 를 구하라.
subsequence of sequence
단조 증가하는 X의 index sequence
ex) X = <A, B, C, B, D, A, B>, Z = <B, C, D, B> ⇒ <2, 3, 5, 7>
LCS-LENGTH(X, Y)
m = X.length
n = Y.length
let c[0..m,0..n] be new table
for i = 1 to m // 초기화
c[i,0] = 0
for j = 0 to n
c[0,j] = 0
for i = 1 to n
for j = 1 to n
if x_i == y_j
c[i,j] = c[i-1,j-1]+1
elseif c[i-1,j] >= c[i,j-1]
c[i,j] = c[i-1,j]
else
c[i,j] = c[i,j-1]
return c
시간복잡도:
통나무 대신 빵 잘라주세요