Ver3.5 ๐งฉ ๋์ ๊ณํ๋ฒ ์์ ์ ๋ณต

๐งฉ ๋์ ๊ณํ๋ฒ ์์ ์ ๋ณต
"๊ฐ์ ๊ณ์ฐ์ ๋ ๋ฒ ํ์ง ์๋ ์ฒ์ฌ์ ์ธ ๋ฐ์ โ DP์ ์ธ๊ณ๋ก ๋ ๋๋ณด์! ๐"
์ผ, ์์งํ ๋งํ ๊ฒ. ๋์ ๊ณํ๋ฒ(Dynamic Programming, DP)์ ์ฒ์ ๋ค์์ ๋ ์ด๋ฆ๋ถํฐ ๋ญ๊ฐ ๋ฌด์ญ์ง ์์? ๐
"๋์ "์ด๋ผ๋ ๋จ์ด๋ ๊ทธ๋ ๊ณ , "๊ณํ๋ฒ"์ด๋ผ๋ ๋จ์ด๋ ๊ทธ๋ ๊ณ ... ๋ญ๊ฐ ์์ฒญ ๋ณต์กํ ์ํ ์ด๋ก ๊ฐ์ ๋๋.
๊ทผ๋ฐ ๋ง์ ํ๊ณ ๋ค๋ฉด ์ง์ง ์ฐ์ํ๊ณ ์๋ฆ๋ค์ด ์์ด๋์ด์ผ. ์ค๋ ๋๋ ๊ฐ์ด ์ด ์ธ๊ณ๋ฅผ ์์ ํ ๋ฏ์ด๋ณด์! ๐ช
์ด ๊ธ์ ๋ค ์ฝ๊ณ ๋๋ฉด DP๊ฐ ์ ์ํ๊ณผ ์ปดํจํฐ๊ณผํ์์ ๊ทธํ ๋ก ์ค์ํ์ง, ๊ทธ๋ฆฌ๊ณ ์ด๋ป๊ฒ ์ฐ์ด๋์ง ํ์คํ ์๊ฒ ๋ ๊ฑฐ์ผ.
๋์ ๊ณํ๋ฒ์ 1950๋
๋ ๋ฏธ๊ตญ์ ์ํ์ ๋ฆฌ์ฒ๋ ๋ฒจ๋ง(Richard Bellman)์ด ๊ฐ๋ฐํ ์ต์ ํ ๊ธฐ๋ฒ์ด์ผ.
์ด๋ฆ์ด ์ข ์ด์ํ์ง? "Dynamic Programming"์ธ๋ฐ ์ฌ์ค ์ฌ๊ธฐ์ "Dynamic"์ ์ฐ๋ฆฌ๊ฐ ํํ ์ฐ๋ "๋์ ์ธ"์ ์๋ฏธ๊ฐ ์๋์ผ.
๋ฒจ๋ง ๋ณธ์ธ์ด ๋์ค์ ๋ฐํ๊ธธ, ๋น์ ์ฐ๊ตฌ๋น๋ฅผ ์ง์ํ๋ ๊ตญ๋ฐฉ๋ถ๊ฐ "์ํ ์ฐ๊ตฌ"๋ผ๋ ๋จ์ด๋ฅผ ์ซ์ดํด์ ๊ทธ๋ฅ ๋ฉ์์ด ๋ณด์ด๋ ์ด๋ฆ์ ๊ณจ๋๋ค๊ณ ํด ๐
๊ทธ๋ฌ๋๊น ์ด๋ฆ์ ๋๋ฌด ๊ฒ๋จน์ง ๋ง!
์ด๊ฒ ์ ๋ถ์ผ. ์ง์ง๋ก. ๋ฌผ๋ก ์ด๊ฑธ ์ค์ ๋ก ๊ตฌํํ๋ ๊ฑด ๋ค์ํ ๊ธฐ์ ๊ณผ ํต์ฐฐ์ด ํ์ํ์ง๋ง,
ํต์ฌ ์ฒ ํ์ ๋ฑ ์ด ํ ์ค์ด์ผ. ์ค๋ณต ๊ณ์ฐ์ ์์ ์ ํจ์จ์ ๊ทน์ ์ผ๋ก ๋์ด๋ ๊ฒ.
ํฐ ๋ฌธ์ ์ ์ต์ ํด๊ฐ ์์ ๋ถ๋ถ ๋ฌธ์ ๋ค์ ์ต์ ํด๋ก ๊ตฌ์ฑ๋ ์ ์์ด์ผ ํด.
์๋ฅผ ๋ค์ด ์์ธ์์ ๋ถ์ฐ๊น์ง ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ๋๋ค๋ฉด, ๊ทธ ๊ฒฝ๋ก ์์ ์ด๋ค ์ค๊ฐ ๋์๋ฅผ ๊ฑฐ์ณ๋ ๊ทธ ๊ตฌ๊ฐ์ ์ต๋จ ๊ฒฝ๋ก๊ฐ ํฌํจ๋์ด ์์ด์ผ ํ๋ค๋ ๊ฑฐ์ผ.
๊ฐ์ ๋ถ๋ถ ๋ฌธ์ ๊ฐ ๋ฐ๋ณตํด์ ๋ฑ์ฅํด์ผ ํด.
๋ง์ฝ ๋ชจ๋ ๋ถ๋ถ ๋ฌธ์ ๊ฐ ๋ฑ ํ ๋ฒ์ฉ๋ง ๋์จ๋ค๋ฉด ๊ตณ์ด DP๋ฅผ ์ธ ํ์๊ฐ ์์ด. ๊ทธ๋ฅ ๋ถํ ์ ๋ณต์ผ๋ก ํด๊ฒฐํ๋ฉด ๋๊ฑฐ๋ .
์ด ๋ ์กฐ๊ฑด์ด ๋ชจ๋ ๋ง์กฑ๋ ๋ DP๋ ๋ง๋ฒ ๊ฐ์ ํจ์จ์ ๋ฐํํด. ์ง๊ธ๋ถํฐ ๊ตฌ์ฒด์ ์ธ ์์๋ก ์ดํด๋ณด์!
DP๋ฅผ ์ค๋ช
ํ ๋ ๊ฐ์ฅ ๋ง์ด ์ฐ์ด๋ ์์๊ฐ ๋ฐ๋ก ํผ๋ณด๋์น ์์ด์ด์ผ.
ํผ๋ณด๋์น ์์ด์ ์ด๋ ๊ฒ ์ ์๋ผ:
F(n) = F(n-1) + F(n-2) (n โฅ 2)
์ฆ, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ... ์ด๋ ๊ฒ ์ด์ด์ง๋ ์์ด์ด์ผ.
์ด๊ฑธ ์์งํ๊ฒ ์ฌ๊ท๋ก ๊ตฌํํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
์ฝ๋๋ ๊น๋ํ๋ฐ... ๋ฌธ์ ๊ฐ ์์ด. F(5)๋ฅผ ๊ณ์ฐํ๋ ๊ณผ์ ์ ๊ทธ๋ฆผ์ผ๋ก ๋ณด๋ฉด:
๋ณด์ด์ง? F(3)์ด 2๋ฒ, F(2)๊ฐ 3๋ฒ, F(1)์ด ๋ฌด๋ ค 5๋ฒ ๊ณ์ฐ๋ผ!
n์ด ์ปค์ง์๋ก ์ด ์ค๋ณต์ ๊ธฐํ๊ธ์์ ์ผ๋ก ๋์ด๋. F(50)์ ์ด๋ ๊ฒ ๊ณ์ฐํ๋ฉด ์์ญ์ต ๋ฒ์ ์ฐ์ฐ์ด ํ์ํด ๐ฑ
์๊ฐ ๋ณต์ก๋๊ฐ O(2โฟ)์ด๊ฑฐ๋ . ์์ ํญ๋ฐ์ ์ผ๋ก ๋์ด๋๋ ๊ฑฐ์ผ.
DP์ ์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์ธ ๋ฉ๋ชจ์ด์ ์ด์
(Memoization)์ ์จ๋ณด์.
"์ด๋ฏธ ๊ณ์ฐํ ๊ฐ์ ์ ์ฅํด๋๊ณ , ๋ค์ ํ์ํ๋ฉด ๊บผ๋ด ์ด๋ค"๋ ์์ด๋์ด์ผ.
memo = {}
def fib_dp(n):
if n <= 1:
return n
if n in memo: # ์ด๋ฏธ ๊ณ์ฐํ์ผ๋ฉด ๋ฐ๋ก ๋ฐํ!
return memo[n]
memo[n] = fib_dp(n-1) + fib_dp(n-2)
return memo[n]
์ด์ ์๊ฐ ๋ณต์ก๋๊ฐ O(n)์ผ๋ก ์ค์ด๋ค์ด! ๊ฐ ๊ฐ์ ๋ฑ ํ ๋ฒ์ฉ๋ง ๊ณ์ฐํ๋๊น.
F(50)๋ ์์๊ฐ์ ๊ณ์ฐ๋ผ. ์ด๊ฒ DP์ ๋ง๋ฒ์ด์ผ โจ
๋ฉ๋ชจ์ด์ ์ด์
์ด "์์์ ์๋๋ก(Top-Down)" ๋ฐฉ์์ด๋ผ๋ฉด,
๋ฐํ
์
(Bottom-Up)์ "์๋์์ ์๋ก" ์ฌ๋ผ๊ฐ๋ ๋ฐฉ์์ด์ผ.
์์ ๋ฌธ์ ๋ถํฐ ์ฐจ๋ก์ฐจ๋ก ํ์ด๋๊ฐ๋ ๊ฑฐ์ง.
def fib_bottom_up(n):
if n <= 1:
return n
dp = [0] * (n + 1)
dp[0] = 0
dp[1] = 1
for i in range(2, n + 1):
dp[i] = dp[i-1] + dp[i-2] # ์ด๋ฏธ ๊ณ์ฐ๋ ๊ฐ ํ์ฉ!
return dp[n]
์ด ๋ฐฉ์์ ์ฌ๊ท ํธ์ถ์ด ์์ด์ ์คํ ์ค๋ฒํ๋ก์ฐ ๊ฑฑ์ ๋ ์๊ณ , ๋ฉ๋ชจ๋ฆฌ๋ ๋ ํจ์จ์ ์ผ๋ก ์ธ ์ ์์ด.
์ฌ์ง์ด ๋ณ์ ๋ ๊ฐ๋ง ์จ์ O(1) ๊ณต๊ฐ์ผ๋ก๋ ๊ตฌํ ๊ฐ๋ฅํด!
| ๋ฐฉ๋ฒ | ์๊ฐ ๋ณต์ก๋ | ๊ณต๊ฐ ๋ณต์ก๋ | ํน์ง |
|---|---|---|---|
| ์์ ์ฌ๊ท | O(2โฟ) | O(n) | ์ง๊ด์ ์ด์ง๋ง ๋งค์ฐ ๋๋ฆผ |
| ๋ฉ๋ชจ์ด์ ์ด์ (Top-Down) | O(n) | O(n) | ์ฌ๊ท + ์บ์ฑ |
| ๋ฐํ ์ (Bottom-Up) | O(n) | O(n) ~ O(1) | ๋ฐ๋ณต๋ฌธ, ์์ ์ |
DP์ ํด๋์ ์ค์ ํด๋์! ๋ฐฐ๋ญ ๋ฌธ์ ์ผ. ๐
์ด ๋ฌธ์ ๋ ์ํ, ๊ฒฝ์ ํ, ์ปดํจํฐ๊ณผํ ์ ๋ฐ์์ ์์ฒญ๋๊ฒ ์ค์ํ๊ฒ ๋ค๋ค์ ธ.
๋ฌธ์ ์ํฉ์ ์ด๋:
๋ฐฐ๋ญ์ ๋ฃ์ ์ ์๋ ๋ฌผ๊ฑด๋ค์ ๊ฐ์น ํฉ์ ์ต๋๋ก ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น?
(๋จ, ๊ฐ ๋ฌผ๊ฑด์ ํ ๋ฒ์ฉ๋ง ๋ฃ์ ์ ์์ด โ 0/1 ๋ฐฐ๋ญ ๋ฌธ์ )
๋ฐฐ๋ญ ๋ฌธ์ ์ DP ์ ํ์์ ์ด๋:
dp[i][w] = max(dp[i-1][w], dp[i-1][w - weight[i]] + value[i])
โ i๋ฒ์งธ ๋ฌผ๊ฑด์ ์ ๋ฃ๋ ๊ฒฝ์ฐ: dp[i-1][w]
โ i๋ฒ์งธ ๋ฌผ๊ฑด์ ๋ฃ๋ ๊ฒฝ์ฐ: dp[i-1][w - weight[i]] + value[i]
์ด ์ ํ์์ด ํต์ฌ์ด์ผ. "๋ฃ์๊น ๋ง๊น"๋ฅผ ์ ํํ๋ ๊ฑฐ์ผ.
์ด๊ฑธ ํ๋ก ์ฑ์๋๊ฐ๋ฉด O(n ร W)์ ์๊ฐ ๋ณต์ก๋๋ก ์ต์ ํด๋ฅผ ๊ตฌํ ์ ์์ด!
์์ ํ์์ด๋ผ๋ฉด 2โฟ๊ฐ์ง๋ฅผ ๋ค ๋ด์ผ ํ๋๋ฐ, DP๋ฅผ ์ฐ๋ฉด ํจ์ฌ ๋น ๋ฅด๊ฒ ํด๊ฒฐ๋์ง.
def knapsack(weights, values, W):
n = len(weights)
dp = [[0] * (W + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for w in range(W + 1):
# ๋ฌผ๊ฑด์ ์ ๋ฃ๋ ๊ฒฝ์ฐ
dp[i][w] = dp[i-1][w]
# ๋ฌผ๊ฑด์ ๋ฃ์ ์ ์๊ณ , ๋ฃ๋ ๊ฒ ๋ ์ด๋์ด๋ฉด
if weights[i-1] <= w:
dp[i][w] = max(dp[i][w],
dp[i-1][w - weights[i-1]] + values[i-1])
return dp[n][W]
LCS(Longest Common Subsequence)๋ ๋ ๋ฌธ์์ด์์ ๊ณตํต์ผ๋ก ๋ํ๋๋ ๊ฐ์ฅ ๊ธด ๋ถ๋ถ ์์ด์ ์ฐพ๋ ๋ฌธ์ ์ผ.
์ด๊ฒ ์ ์ค์ํ๋๊ณ ? DNA ์์ด ๋ถ์, ํ์ผ ๋น๊ต(diff), ๋ฒ์ ๊ด๋ฆฌ ์์คํ
๋ฑ์ ์ค์ ๋ก ์ฐ์ฌ!
โ "BCAB" ๋๋ "BDAB" (๊ธธ์ด 4)
X[i] != Y[j]์ด๋ฉด: dp[i][j] = max(dp[i-1][j], dp[i][j-1])
์ด ์ ํ์๋ ์ง๊ด์ ์ด์ผ:
๋ ๋ฌธ์๊ฐ ๊ฐ์ผ๋ฉด ์ด์ ๊ฒฐ๊ณผ์ 1์ ๋ํ๊ณ ,
๋ค๋ฅด๋ฉด ํ ์ชฝ์ ์ ์ธํ์ ๋์ ์ต๋๊ฐ์ ์ทจํ๋ ๊ฑฐ์ผ.
def lcs(X, Y):
m, n = len(X), len(Y)
dp = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(1, m + 1):
for j in range(1, n + 1):
if X[i-1] == Y[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[m][n]
print(lcs("ABCBDAB", "BDCAB")) # ์ถ๋ ฅ: 4
์๊ฐ ๋ณต์ก๋๋ O(m ร n)์ด์ผ. ๋ ๋ฌธ์์ด ๊ธธ์ด์ ๊ณฑ์ ๋น๋กํ๋ ๊ฑฐ์ง.
์์ ํ์์ผ๋ก ํ๋ฉด ์ง์ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋๋ฐ, DP ๋๋ถ์ ๋คํญ ์๊ฐ์ผ๋ก ํด๊ฒฐ๋ผ! ๐
DP๋ ๊ทธ๋ํ์์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ๋ ๋ฐ๋ ํต์ฌ์ ์ผ๋ก ์ฐ์ฌ.
๋ํ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ด ๋ฒจ๋ง-ํฌ๋(Bellman-Ford)์ ํ๋ก์ด๋-์์
(Floyd-Warshall)์ด์ผ.
๋ชจ๋ ์์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ํ ๋ฒ์ ๊ตฌํ๋ ์๊ณ ๋ฆฌ์ฆ์ด์ผ.
ํต์ฌ ์์ด๋์ด: "k๋ฒ ๋
ธ๋๋ฅผ ๊ฑฐ์ณ์ ๊ฐ๋ฉด ๋ ์งง์์ง์ง ์์๊น?"
def floyd_warshall(graph, n):
dist = [[float('inf')] * n for _ in range(n)]
# ์ด๊ธฐํ
for i in range(n):
dist[i][i] = 0
for u, v, w in graph:
dist[u][v] = w
# ๋ชจ๋ ์ค๊ฐ ๋
ธ๋ k๋ฅผ ์๋
for k in range(n):
for i in range(n):
for j in range(n):
if dist[i][k] + dist[k][j] < dist[i][j]:
dist[i][j] = dist[i][k] + dist[k][j]
return dist
์๊ฐ ๋ณต์ก๋ O(nยณ)์ด์ง๋ง, ๋ชจ๋ ์์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ํ ๋ฒ์ ๊ตฌํ ์ ์์ด.
์ด ์๊ณ ๋ฆฌ์ฆ๋ DP์ ํต์ฌ ์๋ฆฌ์ธ "์ด๋ฏธ ๊ณ์ฐํ ์ต์ ํด๋ฅผ ์ฌํ์ฉ"ํ๋ ๊ฑฐ์ผ.
์ด๊ฒ๋ DP์ ๋ํ ๋ฌธ์ ์ผ! ์ค์ํ์์๋ ๋ฐ๋ก ์ฐ๊ฒฐ๋๋ ๋ฌธ์ ๊ฑฐ๋ .
๋์ ์ ์ข
๋ฅ๊ฐ ์ฃผ์ด์ก์ ๋, ํน์ ๊ธ์ก์ ๋ง๋ค๊ธฐ ์ํ ์ต์ ๋์ ๊ฐ์๋ฅผ ๊ตฌํ๋ ๊ฑฐ์ผ.
๋ชฉํ ๊ธ์ก: 36์
์ต์ ๋์ ๊ฐ์๋? โ 25 + 10 + 1 = 3๊ฐ!
๊ฐ ๋์ coin์ ๋ํด, dp[i - coin] + 1๊ณผ ๋น๊ตํด์ ์ต์๊ฐ ์ ํ
def coin_change(coins, amount):
dp = [float('inf')] * (amount + 1)
dp[0] = 0 # 0์์ ๋ง๋๋ ๋ฐ ํ์ํ ๋์ : 0๊ฐ
for i in range(1, amount + 1):
for coin in coins:
if coin <= i:
dp[i] = min(dp[i], dp[i - coin] + 1)
return dp[amount] if dp[amount] != float('inf') else -1
print(coin_change([1, 5, 10, 25], 36)) # ์ถ๋ ฅ: 3
์ฌ๊ธฐ์ ์ค์ํ ์ ! ํ์ ์๊ณ ๋ฆฌ์ฆ(Greedy)์ผ๋ก๋ ํญ์ ์ต์ ํด๋ฅผ ๊ตฌํ ์ ์์ด.
์๋ฅผ ๋ค์ด ๋์ ์ด [1, 3, 4]์ด๊ณ ๋ชฉํ๊ฐ 6์ด๋ผ๋ฉด:
ํ์: 4 + 1 + 1 = 3๊ฐ
DP: 3 + 3 = 2๊ฐ โ ๋ ์ ์ด!
์ด๋ฐ ๊ฒฝ์ฐ์ DP๊ฐ ์ง๊ฐ๋ฅผ ๋ฐํํ๋ ๊ฑฐ์ผ ๐ช
LIS(Longest Increasing Subsequence)๋ ์์ด์์ ์์๋ฅผ ์ ์งํ๋ฉด์ ์ฆ๊ฐํ๋ ๊ฐ์ฅ ๊ธด ๋ถ๋ถ ์์ด์ ์ฐพ๋ ๋ฌธ์ ์ผ.
์ฃผ์ ๋ถ์, ํจํด ์ธ์ ๋ฑ์ ํ์ฉ๋ผ!
LIS: [2, 3, 7, 101] ๋๋ [2, 5, 7, 101] โ ๊ธธ์ด 4
def lis(arr):
n = len(arr)
dp = [1] * n # ๊ฐ ์์ ์์ฒด๋ง์ผ๋ก ๊ธธ์ด 1
for i in range(1, n):
for j in range(i):
if arr[j] < arr[i]: # ์ฆ๊ฐํ๋ ๊ฒฝ์ฐ
dp[i] = max(dp[i], dp[j] + 1)
return max(dp)
print(lis([10, 9, 2, 5, 3, 7, 101, 18])) # ์ถ๋ ฅ: 4
์ด O(nยฒ) ํ์ด๋ฅผ ์ด์ง ํ์์ ํ์ฉํ๋ฉด O(n log n)์ผ๋ก ๋ ๋น ๋ฅด๊ฒ ํ ์๋ ์์ด!
DP๋ ์ด๋ ๊ฒ ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ๊ณผ ๊ฒฐํฉํด์ ๋ ๊ฐ๋ ฅํด์ง๊ธฐ๋ ํด.
DP ๋ฌธ์ ๋ฅผ ์ฒ์ ๋ณด๋ฉด ๋ง๋งํ์ง? ๐ ๊ทผ๋ฐ ์ฒด๊ณ์ ์ธ ์ ๊ทผ๋ฒ์ด ์์ด!
dp[i], dp[i][j] ๋ฑ โ ๋ฌด์์ ์ ์ฅํ ์ง ๋ช ํํ ์ ์ํด.
"dp[i]๋ ~์ผ ๋์ ์ต์ ๊ฐ์ด๋ค"๋ผ๊ณ ๋ง๋ก ์ค๋ช ํ ์ ์์ด์ผ ํด.
ํฐ ๋ฌธ์ ๋ฅผ ์์ ๋ฌธ์ ๋ก ์ด๋ป๊ฒ ์ชผ๊ฐค ์ ์๋์ง ๊ด๊ณ์์ ์ฐพ์.
์ด๊ฒ DP์ ํต์ฌ์ด์ ๊ฐ์ฅ ์ด๋ ค์ด ๋ถ๋ถ์ด์ผ.
๊ฐ์ฅ ์์ ๋ถ๋ถ ๋ฌธ์ ์ ๋ต์ ์ง์ ์ค์ ํด.
์: dp[0] = 0, dp[1] = 1 ๋ฑ
๋ฐํ ์ ์ด๋ผ๋ฉด ์ด๋ค ์์๋ก ์ฑ์๋๊ฐ์ง ๊ฒฐ์ ํด.
์์ ๋ฌธ์ ๊ฐ ๋จผ์ ๊ณ์ฐ๋์ด์ผ ํฐ ๋ฌธ์ ์ ์ธ ์ ์์ด.
dp ํ ์ด๋ธ์์ ์ํ๋ ๋ต์ด ์ด๋์ ์๋์ง ํ์ธํด.
dp[n], dp[n][m] ๋ฑ ๋ฌธ์ ์ ๋ฐ๋ผ ๋ฌ๋ผ์ ธ.
| ํจ๋ฌ๋ค์ | ํต์ฌ ์์ด๋์ด | ์ ์ฉ ์กฐ๊ฑด | ์์ |
|---|---|---|---|
| ๋์ ๊ณํ๋ฒ | ์ค๋ณต ๋ถ๋ถ ๋ฌธ์ ์ ์ฅยท์ฌํ์ฉ | ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ + ์ค๋ณต ๋ถ๋ถ ๋ฌธ์ | ๋ฐฐ๋ญ, LCS, LIS |
| ๋ถํ ์ ๋ณต | ๋ฌธ์ ๋ฅผ ๋ ๋ฆฝ์ ์ผ๋ก ๋ถํ | ๋ถ๋ถ ๋ฌธ์ ๊ฐ ๋ ๋ฆฝ์ | ๋ณํฉ ์ ๋ ฌ, ํต ์ ๋ ฌ |
| ํ์ ์๊ณ ๋ฆฌ์ฆ | ๋งค ์๊ฐ ์ต์ ์ ์ ํ | ํ์ ์ ํ ์์ฑ ์ฑ๋ฆฝ | ๋ค์ต์คํธ๋ผ, ํํ๋ง |
| ์์ ํ์ | ๋ชจ๋ ๊ฒฝ์ฐ์ ์ ํ์ | ํญ์ ๊ฐ๋ฅํ์ง๋ง ๋๋ฆผ | ๋ธ๋ฃจํธ ํฌ์ค |
๊ธฐ๋ณธ์ ๋ง์คํฐํ๋ค๋ฉด ์ด์ ๊ณ ๊ธ ๊ธฐ๋ฒ๋ค์ ์ดํด๋ณด์! ๐ฅ
์ด ๊ธฐ๋ฒ๋ค์ ๊ฒฝ์ ํ๋ก๊ทธ๋๋ฐ์ด๋ ๊ณ ๊ธ ์๊ณ ๋ฆฌ์ฆ ์์
์์ ์์ฃผ ๋ฑ์ฅํด.
์ํ๋ฅผ ๋นํธ(0๊ณผ 1)๋ก ํํํด์ ์งํฉ์ ํจ์จ์ ์ผ๋ก ๋ค๋ฃจ๋ ๊ธฐ๋ฒ์ด์ผ.
๋ํ์ ์ธ ๋ฌธ์ ๊ฐ ์ธํ์ ์ํ(TSP, Traveling Salesman Problem)์ผ!
์์ ํ์: O(n!) โ ๋นํธ๋ง์คํฌ DP: O(2โฟ ร nยฒ) โ ํจ์ฌ ๋น ๋ฆ!
# TSP ๋นํธ๋ง์คํฌ DP
# dp[visited][ํ์ฌ๋์] = ๋ฐฉ๋ฌธํ ๋์ ์งํฉ์ด visited์ด๊ณ
# ํ์ฌ ๋์์ ์์ ๋์ ์ต์ ๋น์ฉ
def tsp(dist, n):
INF = float('inf')
dp = [[INF] * n for _ in range(1 << n)]
dp[1][0] = 0 # ๋์ 0์์ ์์, ๋์ 0๋ง ๋ฐฉ๋ฌธ
for visited in range(1 << n):
for cur in range(n):
if dp[visited][cur] == INF:
continue
for next_city in range(n):
if visited & (1 << next_city): # ์ด๋ฏธ ๋ฐฉ๋ฌธ
continue
next_visited = visited | (1 << next_city)
dp[next_visited][next_city] = min(
dp[next_visited][next_city],
dp[visited][cur] + dist[cur][next_city]
)
# ๋ชจ๋ ๋์ ๋ฐฉ๋ฌธ ํ ์ถ๋ฐ์ง๋ก ๋ณต๊ท
all_visited = (1 << n) - 1
return min(dp[all_visited][i] + dist[i][0] for i in range(n))
๊ตฌ๊ฐ [i, j]์ ๋ํ ์ต์ ํด๋ฅผ ๊ตฌํ๋ DP์ผ.
๋ํ ๋ฌธ์ : ํ๋ ฌ ์ฐ์ ๊ณฑ์
(Matrix Chain Multiplication)
ํ๋ ฌ Aโ ร Aโ ร Aโ ร Aโ๋ฅผ ๊ณ์ฐํ ๋ ์ด๋ค ์์๋ก ๊ณฑํ๋๋์ ๋ฐ๋ผ
์ฐ์ฐ ํ์๊ฐ ์์ฒญ๋๊ฒ ๋ฌ๋ผ์ ธ. DP๋ก ์ต์ ์์๋ฅผ O(nยณ)์ ์ฐพ์ ์ ์์ด!
๊ธฐ๋ฒ 1 ์ฌ๋ผ์ด๋ฉ ์๋์ฐ ์ต์ ํ ์ ํ์์ด ํน์ ๋ฒ์์ ์ต์๊ฐ/์ต๋๊ฐ์ ์์กดํ ๋ ๋ฑ(Deque)์ ํ์ฉํด O(n)์ผ๋ก ์ต์ ํ
๊ธฐ๋ฒ 2 ๋ถํ ์ ๋ณต ์ต์ ํ
์ ํ์์ ์ต์ ๋ถํ ์ ์ด ๋จ์กฐ ์ฆ๊ฐํ ๋ O(nยฒ log n) โ O(n log n)์ผ๋ก ์ต์ ํ
๊ธฐ๋ฒ 3 ๋ณผ๋ก ๊ป์ง ํธ๋ฆญ (CHT)
์ ํ์์ด ์ ํ ํจ์์ ์ต์๊ฐ ํํ์ผ ๋ O(nยฒ) โ O(n)์ผ๋ก ์ต์ ํ
๊ธฐ๋ฒ 4 ๊ณต๊ฐ ์ต์ ํ
2D DP๋ฅผ 1D๋ก ์ค์ด๊ฑฐ๋, ๋กค๋ง ๋ฐฐ์ด์ ์ฌ์ฉํด ๋ฉ๋ชจ๋ฆฌ ์ ์ฝ
DP๋ ์ด๋ก ์๋ง ๋จธ๋ฌผ์ง ์์. ์ฐ๋ฆฌ ์ผ์ ๊ณณ๊ณณ์ ์จ์ด์์ด! ๐
๋ ๋ฌธ์์ด ์ฌ์ด์ ํธ์ง ๊ฑฐ๋ฆฌ(Levenshtein Distance)๋ ๋ง์ถค๋ฒ ๊ต์ , ๊ฒ์ ์์ง, ์์ฐ์ด ์ฒ๋ฆฌ์ ํต์ฌ์ ์ผ๋ก ์ฐ์ฌ.
ํ ๋ฌธ์์ด์ ๋ค๋ฅธ ๋ฌธ์์ด๋ก ๋ฐ๊พธ๊ธฐ ์ํ ์ต์ ํธ์ง ํ์(์ฝ์
, ์ญ์ , ๊ต์ฒด)๋ฅผ ๊ตฌํ๋ ๊ฑฐ์ผ.
X[i] != Y[j]์ด๋ฉด: dp[i][j] = 1 + min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])
โ ๊ฐ๊ฐ ์ญ์ , ์ฝ์ , ๊ต์ฒด์ ํด๋น
์๋ฅผ ๋ค์ด "kitten"๊ณผ "sitting"์ ํธ์ง ๊ฑฐ๋ฆฌ๋ 3์ด์ผ.
์ด ์๊ณ ๋ฆฌ์ฆ ๋๋ถ์ ์ฐ๋ฆฌ๊ฐ ์คํ๋ฅผ ์ณ๋ ๊ฒ์ ์์ง์ด "ํน์ ์ด๊ฑธ ์ฐพ์ผ์
จ๋์?"๋ผ๊ณ ์ ์ํด์ค ์ ์๋ ๊ฑฐ์ผ! ๐
์์ฑ ์ธ์, ์์ฐ์ด ์ฒ๋ฆฌ์์ ์ฐ์ด๋ DP ๊ธฐ๋ฐ ์๊ณ ๋ฆฌ์ฆ์ด์ผ.
์๋ ๋ง๋ฅด์ฝํ ๋ชจ๋ธ(HMM)์์ ๊ฐ์ฅ ๊ฐ๋ฅ์ฑ ๋์ ์ํ ์ํ์ค๋ฅผ ์ฐพ๋ ๋ฐ ์ฌ์ฉ๋ผ.
์ค๋งํธํฐ์ ์์ฑ ์ธ์, ์๋ ๋ฒ์ญ ๋ฑ์ ํต์ฌ์ ์ผ๋ก ํ์ฉ๋๋ ๊ธฐ์ ์ด์ผ!
DP๋ ๋จ์ํ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ๋ฒ์ด ์๋์ผ. ํํํ ์ํ์ ๊ธฐ๋ฐ ์์ ์ ์์ด.
๊ฐํํ์ต์ ํต์ฌ์ด๊ธฐ๋ ํ ๋ฒจ๋ง ๋ฐฉ์ ์์ DP์ ์ํ์ ํํ์ด์ผ:
R(s,a): ํ๋ a๋ฅผ ํ์ ๋ ๋ฐ๋ ๋ณด์
ฮณ: ํ ์ธ์จ (๋ฏธ๋ ๋ณด์์ ํ์ฌ ๊ฐ์น)
P(s'|s,a): ์ํ ์ ์ด ํ๋ฅ
์ด ๋ฐฉ์ ์์ด ๋ฐ๋ก ํ๋ AI์ ๊ฐํํ์ต(Reinforcement Learning)์ ๊ทผ๊ฐ์ด์ผ.
์ํ๊ณ (AlphaGo)๋ ์ด ์๋ฆฌ๋ฅผ ํ์ฉํ์ด! ๐ค
| ๋ฌธ์ | ์์ ํ์ | DP ์๊ฐ | DP ๊ณต๊ฐ |
|---|---|---|---|
| ํผ๋ณด๋์น | O(2โฟ) | O(n) | O(1)~O(n) |
| ๋ฐฐ๋ญ ๋ฌธ์ | O(2โฟ) | O(nW) | O(nW) |
| LCS | O(2โฟ) | O(mn) | O(mn) |
| LIS | O(2โฟ) | O(nยฒ) | O(n) |
| ํ๋ก์ด๋-์์ | O(n!) | O(nยณ) | O(nยฒ) |
| TSP (๋นํธ๋ง์คํฌ) | O(n!) | O(2โฟยทnยฒ) | O(2โฟยทn) |
ํ๋ฅผ ๋ณด๋ฉด ์ ์ ์๋ฏ์ด, DP๋ ์ง์ ์๊ฐ์ด๋ ํฉํ ๋ฆฌ์ผ ์๊ฐ์ ๋คํญ ์๊ฐ ๋๋ ์ง์ ์๊ฐ์ ๋ ๋ฎ์ ์ฐจ์๋ก ์ค์ฌ์ค.
์ด๊ฒ DP๊ฐ ๊ทธํ ๋ก ๊ฐ๋ ฅํ ์ด์ ์ผ!
DP๋ฅผ ์ ๋๋ก ๋ง์คํฐํ๊ณ ์ถ๋ค๋ฉด ์ด๋ฐ ์์๋ก ๊ณต๋ถํ๋ ๊ฑธ ์ถ์ฒํด!
๋ฉ๋ชจ์ด์ ์ด์ ๋ฐํ ์ 1D DP
2D DP ์ ํ์ ์ค๊ณ ๊ณต๊ฐ ์ต์ ํ
๋นํธ๋ง์คํฌ ๊ตฌ๊ฐ DP TSP
CHT ๋ถํ ์ ๋ณต ์ต์ ํ ๋จ์กฐ ๋ฑ
์ฐธ๊ณ ๋ก, ์๊ณ ๋ฆฌ์ฆ๊ณผ ์ํ ์ค๋ ฅ์ ํค์ฐ๊ณ ์ถ๋ค๋ฉด ์ฌ๋ฅ๋ท(jaenung.net)์์ ์๊ณ ๋ฆฌ์ฆ ํํฐ๋ง ์ฌ๋ฅ์ ์ฐพ์๋ณผ ์๋ ์์ด!
๋ค์ํ ์ ๋ฌธ๊ฐ๋ค์ด DP๋ฅผ ํฌํจํ ์๊ณ ๋ฆฌ์ฆ์ 1:1๋ก ๊ฐ๋ฅด์ณ์ฃผ๋ ์๋น์ค๋ฅผ ์ ๊ณตํ๊ณ ์๊ฑฐ๋ . ํผ์ ๊ณต๋ถํ๋ค ๋งํ๋ฉด ์ ๋ฌธ๊ฐ์ ๋์์ ๋ฐ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ ๐
โ ์ํ ์ ์๋ฅผ ๋ชจํธํ๊ฒ ํ๋ ๊ฒ dp[i]๊ฐ ์ ํํ ๋ฌด์์ ์๋ฏธํ๋์ง ๋ช ํํ์ง ์์ผ๋ฉด ์ ํ์์ ์ธ์ธ ์ ์์ด.
โ ์ด๊ธฐ๊ฐ(Base Case)์ ๋น ๋จ๋ฆฌ๋ ๊ฒ
dp[0]์ด๋ dp[1] ๊ฐ์ ๊ธฐ์ ์ฌ๋ก๋ฅผ ์๋ชป ์ค์ ํ๋ฉด ์ ์ฒด ๊ฒฐ๊ณผ๊ฐ ํ๋ ค.
โ ๊ณ์ฐ ์์๋ฅผ ์๋ชป ์ก๋ ๊ฒ
๋ฐํ
์
์์ dp[i]๋ฅผ ๊ณ์ฐํ ๋ ํ์ํ dp[j](j < i)๊ฐ ์์ง ๊ณ์ฐ ์ ๋์ผ๋ฉด ์ ๋ผ.
โ ๋ฉ๋ชจ๋ฆฌ ์ด๊ณผ๋ฅผ ๊ณ ๋ คํ์ง ์๋ ๊ฒ
2D DP ๋ฐฐ์ด์ด ๋๋ฌด ํฌ๋ฉด ๋ฉ๋ชจ๋ฆฌ ์ด๊ณผ๊ฐ ๋ ์ ์์ด. ๊ณต๊ฐ ์ต์ ํ๋ฅผ ๊ณ ๋ คํด์ผ ํด.
๋ง์ง๋ง์ผ๋ก ์์ ํ DP ๋ฌธ์ ํ๋๋ฅผ ์ฒ์๋ถํฐ ๋๊น์ง ํ์ด๋ณด์!
n๋ฒ์งธ ๊ณ๋จ์ ์ค๋ฅด๋ ๋ฐฉ๋ฒ์ ์๋?
(i-1๋ฒ์งธ์์ 1์นธ ์ค๋ฅด๊ฑฐ๋, i-2๋ฒ์งธ์์ 2์นธ ์ค๋ฅด๊ฑฐ๋)
def climb_stairs(n):
if n <= 2:
return n
dp = [0] * (n + 1)
dp[1] = 1
dp[2] = 2
for i in range(3, n + 1):
dp[i] = dp[i-1] + dp[i-2]
return dp[n]
# ํ
์คํธ
for i in range(1, 8):
print(f"๊ณ๋จ {i}๊ฐ: {climb_stairs(i)}๊ฐ์ง")
# ์ถ๋ ฅ:
# ๊ณ๋จ 1๊ฐ: 1๊ฐ์ง
# ๊ณ๋จ 2๊ฐ: 2๊ฐ์ง
# ๊ณ๋จ 3๊ฐ: 3๊ฐ์ง
# ๊ณ๋จ 4๊ฐ: 5๊ฐ์ง
# ๊ณ๋จ 5๊ฐ: 8๊ฐ์ง
# ๊ณ๋จ 6๊ฐ: 13๊ฐ์ง
# ๊ณ๋จ 7๊ฐ: 21๊ฐ์ง
๋์น์ฑ์ด? ๊ฒฐ๊ณผ๊ฐ ํผ๋ณด๋์น ์์ด์ด์ผ! ๐คฉ
์ด๋ ๊ฒ DP ๋ฌธ์ ๋ค์ ์๋ก ์ฐ๊ฒฐ๋์ด ์๊ณ , ๊ฐ์ ํจํด์ด ๋ค์ํ ํํ๋ก ๋ํ๋.
์ด ํจํด์ ์ธ์ํ๋ ๋ฅ๋ ฅ์ด ๋ฐ๋ก DP ๋ง์คํฐ์ ํต์ฌ์ด์ผ!
๊ทธ๋ฆฌ๊ณ ์ฌ๋ฅ๋ท์์ ์ํ์ด๋ ์๊ณ ๋ฆฌ์ฆ ๊ด๋ จ ์ฌ๋ฅ์ ๊ณต์ ํ๊ฑฐ๋ ๋ฐฐ์ธ ์ ์๋ค๋ ๊ฒ๋ ๊ธฐ์ตํด์ค.
DP ๊ฐ์ ์ด๋ ค์ด ๊ฐ๋
๋ ์ข์ ์ ์๋๊ณผ ํจ๊ป๋ผ๋ฉด ํจ์ฌ ๋น ๋ฅด๊ฒ ์ดํดํ ์ ์๊ฑฐ๋ ! ๐ฏ
์, ์ด์ ๋์ ๊ณํ๋ฒ์ ์ธ๊ณ๋ฅผ ๊ฝค ๊น์ด ํํํ์ด! ๐
์ฒ์์ ์ด๋ฆ๋ถํฐ ๋ฌด์์ ๋ DP๊ฐ ์ด์ ์ข ์น๊ทผํ๊ฒ ๋๊ปด์ง์ง ์์?
DP์ ํต์ฌ์ ๋ค์ ํ๋ฒ ์ ๋ฆฌํ๋ฉด:
โ ํฐ ๋ฌธ์ ๋ฅผ ์์ ๋ถ๋ถ ๋ฌธ์ ๋ก ์ชผ๊ฐ๊ธฐ โ ๋ถํ ์ ๊ธฐ์
โ ์ด๋ฏธ ๊ณ์ฐํ ๊ฒฐ๊ณผ๋ ์ ์ฅํ๊ธฐ โ ๋ฉ๋ชจ์ด์ ์ด์ ์ ์งํ
โ ์์ ๋ฌธ์ ๋ถํฐ ์ฐจ๋ก๋ก ํ๊ธฐ โ ๋ฐํ ์ ์ ์ฒด๊ณ์ฑ
โ ์ ํ์์ ํตํด ๊ด๊ณ ํํํ๊ธฐ โ ์ํ์ ์ฐ์ํจ
โ ์ง์ ์๊ฐ์ ๋คํญ ์๊ฐ์ผ๋ก ์ค์ด๊ธฐ โ ํจ์จ์ ๋ง๋ฒ
DP๋ ๋จ์ํ ์๊ณ ๋ฆฌ์ฆ ๊ธฐ๋ฒ์ ๋์ด์ ๋ฌธ์ ๋ฅผ ๋ฐ๋ผ๋ณด๋ ์ฌ๊ณ ๋ฐฉ์์ด์ผ.
"์ด ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ์ชผ๊ฐค ์ ์์๊น?", "์ด๋ค ์ ๋ณด๋ฅผ ์ ์ฅํด๋๋ฉด ๋์ค์ ์ธ ์ ์์๊น?"
์ด๋ฐ ์ง๋ฌธ์ ์ต๊ด์ ์ผ๋ก ๋์ง๋ค ๋ณด๋ฉด ์ด๋์ DP ๋ง์คํฐ๊ฐ ๋์ด ์์ ๊ฑฐ์ผ! ๐ช
์ํ๊ณผ ์๊ณ ๋ฆฌ์ฆ์ ์ธ๊ณ๋ ๊น๊ณ ๋์ด. ์ค๋ ๋ฐฐ์ด DP๋ ๊ทธ ์ธ๊ณ์ ์์ฃผ ์ค์ํ ๋ฌธ ํ๋๋ฅผ ์ฐ ๊ฑฐ์ผ.
๊ณ์ ํํํ๊ณ , ๊ณ์ ์ง๋ฌธํ๊ณ , ๊ณ์ ์ฑ์ฅํด! ๐
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.