Dynamic Programming#
Knapsack problem ์ด๋ผ๋ ๋ฐฐ๋ญ ์ฑ์ฐ๊ธฐ ๋ฌธ์ ๋ ์๋ ์ ๋ช ํ๊ณ DP๋ฅผ ์ฒ์ ์ ํ ๋ ๋๋ถ๋ถ ์ด๊ฒ์ผ๋ก ์ ํ๊ฒ ๋๋ค.
knapsack problem
๋ฐฐ๋ญ์ ์ต๋ ์ฉ๋์ W์ด๋ฉฐ, ์ด๋ฅผ ์ด๊ณผํด์ ๋ณด์์ ๋ด์ผ๋ฉด ๋ฐฐ๋ญ์ด ์ฐข์ด์ง๋ค.
๊ฐ ๋ณด์๋ค์ ๋ฌด๊ฒ์ ๊ฐ๊ฒฉ์ ์๊ณ ์๋ค.
๋ฐฐ๋ญ์ด ์ฐข์ด์ง์ง ์๋ ์ ์์ ๊ฐ๊ฒฉ ํฉ์ด ์ต๋๊ฐ ๋๋๋ก ๋ณด์์ ๋ด๋ ๋ฐฉ๋ฒ์ return ํด๋ผ.
์ฌ๊ธฐ์๋ ๋ ๊ฐ์ง ์ข
๋ฅ์ ๋ฌธ์ ๊ฐ ์๋ค. ๋ณด์์ ์๋ฅผ ์ ์๋ fractional knapsack problem
๊ณผ ์๋ฅผ ์ ์๋ค๊ณ ๊ฐ์ ํ๋(๋ฉ์ด๋ฆฌ๋ก) 0-1 knapsack problem
์ด ์๋ค. ๋์ ๊ณํ๋ฒ์ ํ์์ ๋ฌธ์ ๋ฅผ ๋ค๋ฃฐ ๋ ์ฌ์ฉ๋๋ค.
DP๋ ํฐ ๋ฌธ์ ๋ฅผ ์์ ๋ฌธ์ ๋ก ์ชผ๊ฐ์(Devide-and-Conquer), ์ด์ ๊ณ์ฐ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํด์ ๋ฐ๋ณต์ ์ค์ด๋(Memorization) ์ด ๋ ๊ฐ์ง๋ฅผ ํ์ฉํด์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค. ์๋ ์ ๋ช ํ ํผ๋ณด๋์น ์์ด๋ฌธ์ ๋ ์ฌ๊ทํจ์๋ฅผ ์ด์ฉํ๋ dp๋ฅผ ์ฌ์ฉํด์ ํ ์ ์๋ค.
memo = {1:1, 2:1}
def fibo(n):
# initialize
if n == 0:
return 0
elif n == 1:
return 1
# recursive memo
if n not in memo:
memo[n] = fibo(n-1) + fibo(n-2)
return memo[n]
๊ทธ๋ฅ memo๋ฅผ ์ํด๋ ํ ์ ์๊ธด ํ์ง๋ง, ์ด๋ ๊ฒ ์ฌ๊ท์ ์ผ๋ก ์์ ๊ณ์ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ค์์ ํ์ฉํ๋ ๋ฌธ์ ๋ ์ ์ฅ์ ํ๋ ์ํ๋๋์ ๋ฐ๋ผ์ n์ด ์ปค์ง ๊ฒฝ์ฐ์ ์๋์ ์ผ๋ก ์๊ฐ๋ณต์ก๋๊ฐ ์ค์ด๋ ๋ค. ์ด๋ฌํ DP๋ฅผ 0-1 knapsack problem
์ ์ ์ฉํ๋ ค๋ฉด ์ต์ ์ ์๋ฆฌ(principle of optimality)
๊ฐ ์ฑ๋ฆฝํ๋์ง ํ์ธํด์ผํ๋ค. ์ต์ ์ ์๋ฆฌ๋
Principle of Optimality
์ด๋ค ๋ฌธ์ ์ ์ ๋ ฅ ์ฌ๋ก์ ์ต์ ํด๊ฐ ๊ทธ ์ ๋ ฅ ์ฌ๋ก๋ฅผ ๋ถํ ํ ๋ถ๋ถ ์ฌ๋ก์ ๋ํ ์ต์ ํด๋ฅผ ํญ์ ํฌํจํ๊ณ ์์ผ๋ฉด, ๊ทธ ๋ฌธ์ ์ ๋ํ์ฌ ์ต์ ์ ์๋ฆฌ๊ฐ ์ฑ๋ฆฝํ๋ค.
๊ฒฐ๊ตญ ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ด๋ ๊ฒ์ ๋ฌธ์ ๋ฅผ ์์ ๋ฌธ์ ๋ค๋ก ๋๋๊ณ (์ต์ ๋ถ๋ถ๊ตฌ์กฐ optimal substructures), ํ์ ๋ฌธ์ ๊ฐ ๋ฐ๋ณต๋๋(overlapping subproblems) ๊ฒ์ด๋ค. DP๊ฐ ํจ๊ณผ์ ์ด๋ผ๋ฉด ํด๋น ๋ ๊ฐ์ง ์กฐ๊ฑด์ด ๋ง์กฑ๋์ด์ผ๋ง ํ๋ค. ์ด ์กฐ๊ฑด์ด ์ฑ๋ฆฝ๋์ง ์์ผ๋ฉด ์ ์ฉ๋์ง ์๊ฑฐ๋, ํจ์จ์ด ๋จ์ด์ง ์ ์๋ค.
๋น๊ต#
- ์ฌ๊ท ๋ถํ ์ ๋ณต(Divide and Conquer)
DP๋ ์ค๋ณต๋ ๋ถ๋ถ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๋ ์ค๋ณต ๊ณ์ฐ์ ์ค๋ฆฌ๊ธฐ ์ํด ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ๋ผ์ด์ฆํ๋ค. ๋ฐ๋ฉด, ๋ถํ ์ ๋ณต์ ๋ฌธ์ ๋ฅผ ๋ ๋ฆฝ์ ์ธ ํ์ ๋ฌธ์ ๋ก ๋๋๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ํฉ์ณ์ ์ ์ฒด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค. ํ์ ๋ฌธ์ ๋ค์ด ์ค๋ณต๋์ง ์๋ ๊ฒฝ์ฐ DP < ๋ถํ ์ ๋ณต์ด๋ค. ์ ํฉํ ๋ฌธ์ : ํต ์ ๋ ฌ, ๋ณํฉ ์ ๋ ฌ, ์ด์ง ํ์. ํด๋น ๊ฒฝ์ฐ๋ค์ ํ์ ๋ฌธ์ ๊ฐ ์ค๋ณต๋์ง ์๋๋ค. ๋ ๋ฆฝ์ ์ธ ๋ถ๋ถ๋ฌธ์ ๋ค์ ๋ถํ ์ ๋ณต์ด ์ข๋ค.
- ํ์(Greedy)
ํ์ ์๊ณ ๋ฆฌ์ฆ์ ๋งค ๋จ๊ณ์์ ์ต์ ์ ํ, ์ด๋ฌํ ๊ณผ์ ์ ๊ฒฐ๋ก ์ด ๊ฒฐ๊ตญ ์ต์ ํด๋ก ๋๋ฌํ๋ค. ๋ฐ๋ฉด DP๋ ๋ฌธ์ ์ต์ ํ๋ฅผ ์ํด ๊ฐ๋ฅํ ๋ชจ๋ ํ์ ๋ฌธ์ ์ ๊ฒฐ๊ณผ๋ฅผ ๊ณ ๋ คํ๋ค. ์ ํฉํ ๋ฌธ์ : ์ต๋จ ๊ฒฝ๋ก ๋ฌธ์ - ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ํ์์ ์ ๊ทผ์ด ์ ํจํ์ง๋ง, ๊ฐ์ค์น๊ฐ ์์์ธ ๊ฒฝ์ฐ ํ์์ ์ ๊ทผ์ด ์ต์ ํด๋ฅผ ๋ณด์ฅํ์ง ๋ชปํ๋ค. ๋๋ฌธ์ ๋ฒจ๋ง-ํฌ๋ ์๊ณ ๋ฆฌ์ฆ ๊ฐ์ DP ๊ธฐ๋ฒ์ด ํ์ํด์ง๋ค.
- ๋ธ๋ฃจํธํฌ์ค(Brute Force)
DP๋ ์ค๋ณต๋ ๋ถ๋ถ ๋ฌธ์ ์ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํด ์๊ฐ ๋ณต์ก๋๋ฅผ ์ค์ด๋ ๋ฐ๋ฉด, ๋ธ๋ฃจํธํฌ์ค๋ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ํ์ธํ๊ธฐ ๋๋ฌธ์ ์ฐ์ฐ๋์ด ๋น์ฐํ ๋ง์ ์ง ์ ๋ฐ์ ์๋ค.
- ๋ฐฑํธ๋ํน(Backtracking)
backtracking์ ๋ชจ๋ ๊ฐ๋ฅํ ๊ฒฝ๋ก๋ฅผ ํ์ํ๋, ์กฐ๊ฑด์ ๋ง์กฑํ์ง ์๋ ๊ฒฝ์ฐ ๋ฏธ๋ฆฌ ๋ฐฐ์ ํ๋ ๋ฐฉ์์ผ๋ก ๊ฒฝ์ฐ์ ์๋ฅผ ์ค์ฌ์ ํ์ํ๋ค. DP๋ ์ฃผ๋ก ์ํ ์ ์ฅ์ ํตํด ์ค๋ณต ๊ณ์ฐ์ ๋ฐฉ์งํ๊ณ , ๋ฐฑํธ๋ํน์ ๋ถํ์ํ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ง์น๊ธฐํ์ฌ ํจ์จ์ฑ์ ๋์ธ๋ค. ์ ํฉํ ๋ฌธ์ : ๊ฒฝ๋ก ํ์์์ ์ ์ฝ ์กฐ๊ฑด์ด ์์ด, ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ํ์ํ์ง ์์๋ ๋๋ ๊ฒฝ์ฐ ๋ฐฑํธ๋ํน์ด ํจ๊ณผ์ ์ด๋ค. ๋ฐฑํธ๋ํน์ ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ๊ฐ ์ฑ๋ฆฝํ์ง ์๋ ๊ฒฝ์ฐ์๋ ์ฌ์ฉํ ์ ์๋ค. N-Queen, ๋ถ๋ถ ์งํฉ์ ํฉ ๋ฌธ์ ๋ฑ์ด ์๋ค.
์๊ณ ๋ฆฌ์ฆ |
์ ํฉ ์กฐ๊ฑด |
์ฃผ์ ์ฐจ์ด์ |
---|---|---|
๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ (DP) |
์ต์ ๋ถ๋ถ ๊ตฌ์กฐ + ์ค๋ณต๋ ๋ถ๋ถ ๋ฌธ์ |
์ค๋ณต ๊ณ์ฐ์ ์ค์ด๊ธฐ ์ํด ์ด์ ๊ณ์ฐ์ ์ ์ฅ. |
๋ถํ ์ ๋ณต (Divide and Conquer) |
๋ ๋ฆฝ๋ ํ์ ๋ฌธ์ ๋ก ๋๋ ์ ์๋ ๊ฒฝ์ฐ |
์ค๋ณต๋ ๊ณ์ฐ์ด ์๊ณ ๊ฐ ํ์ ๋ฌธ์ ๊ฐ ๋ ๋ฆฝ์ ์ด๋ฉด ์ ํฉ. DP๋ณด๋ค ๊ฐ๋จ. |
ํ์ ์๊ณ ๋ฆฌ์ฆ (Greedy) |
๊ฐ ๋จ๊ณ์ ์ต์ ์ ํ์ด ์ ์ฒด ์ต์ ํด๋ก ์ด์ด์ง ์ ์๋ ๊ฒฝ์ฐ |
๋งค ๋จ๊ณ ์ต์ ์ ํ๋ง ํจ. ์ต์ ํด ๋ณด์ฅ์ด ํ์ํ๋ฉด DP๊ฐ ๋ ์ ํฉ. |
๋ธ๋ฃจํธํฌ์ค (Brute Force) |
๋ฌธ์ ์ ๊ท๋ชจ๊ฐ ์์ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ์๋ํ ์ ์๋ ๊ฒฝ์ฐ |
๊ฐ๋ฅํ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ํ์. ์ค๋ณต ๊ณ์ฐ ์ค์ด๊ธฐ๊ฐ ํ์ํ๋ฉด DP. |
๋ฐฑํธ๋ํน (Backtracking) |
์กฐ๊ฑด์ ํตํด ๋ถํ์ํ ํ์ ๊ฐ์ง์น๊ธฐ๊ฐ ๊ฐ๋ฅํ ๋ |
๊ฐ์ง์น๊ธฐ ํ์ฉ. DP๋ ์ํ ์ ์ฅ์ ํตํด ํจ์จ์ฑ ๊ฐ์ , ๋ฐฑํธ๋ํน์ ์กฐ๊ฑด์ ๋ง์กฑํ์ง ์์ผ๋ฉด ๋ฏธ๋ฆฌ ๋ฐฐ์ . |
A* ์๊ณ ๋ฆฌ์ฆ (A)* |
๊ฒฝ๋ก ํ์์์ ํด๋ฆฌ์คํฑ์ ํตํด ํจ์จ์ฑ์ ๋์ผ ์ ์์ ๋ |
๋น์ฉ๊ณผ ํด๋ฆฌ์คํฑ์ ๋ชจ๋ ๊ณ ๋ คํด ํน์ ๋ฐฉํฅ ํ์. DP๋ ๋ชจ๋ ํ์ ๋ฌธ์ ๋ฅผ ๊ณ ๋ คํด ์ต์ ํ. |
๋ฐฉ๋ฒ๋ก #
ํด๋น ๋ฐฉ๋ฒ์ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ๋ก ์๋ ๋ ๊ฐ์ง๊ฐ ์๋ค. ํ๋๋ ํ๋ค์ด ๋ฐฉ์์ด๊ณ , ๋ค๋ฅธ ํ๋๋ ๋ฐํ ์ ๋ฐฉ์์ด๋ค.
- ํ๋ค์ด
๋ฌธ์ ๋ฅผ ์ฌ๊ท์ ์ผ๋ก ํ๋, ๋ฉ๋ชจ๋ผ์ด์ ์ด์ ๊ธฐ๋ฒ์ผ๋ก ์ ์ฅํด๋๊ณ , ๋ค์ ๊ณ์ฐํ ๋๋ ์ ์ฅ๋ ๊ฐ์ ์ฌ์ฉํ๋ ๋ฐฉ์์ด๋ค. ์ฌ๊ท์ ์ผ๋ก ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ ํจ์ ํธ์ถ ์คํ์ ๊ฐ์ ์ ์ฅํ๋ ๊ตฌ์กฐ์ด๋ฉฐ, ๋ฉ๋ชจ๋ผ์ด์ ์ด์ ์ ํตํด ์ค๋ณต ๊ณ์ฐ์ ํผํ ์ ์๋ค.
def fibonacci(n, memo={}):
if n in memo: # ์ด๋ฏธ ๊ณ์ฐ๋ ๊ฐ์ด ์๋ค๋ฉด ๊ทธ ๊ฐ์ ๋ฐํ
return memo[n]
if n <= 1: # ๊ธฐ๋ณธ ์กฐ๊ฑด
return n
memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo) # ๋ฉ๋ชจ์ด์ ์ด์
return memo[n]
- ๋ฐํ ์ ๋ฐฉ์
์์ ํ์ ๋ฌธ์ ๋ฅผ ๋ฐ๋ณต๋ฌธ์ผ๋ก ์ฌ์ฉํด ์ ์ง์ ์ผ๋ก ํฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ์์ด๋ค. ํ์ ๋ฌธ์ ์ ํด๊ฒฐ ๊ฒฐ๊ณผ๋ฅผ ํ ์ด๋ธ์ ์ ์ฅํ๊ณ , ์ด๋ฅผ ์ ์ฐจ ์์ ๋ฌธ์ ํด๊ฒฐํ์ฌ ๋๊ฐ๋ฉฐ ์ต์ข ์ ์ผ๋ก ์ํ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
def fibonacci(n):
if n <= 1: # ๊ธฐ๋ณธ ์กฐ๊ฑด
return n
dp = [0] * (n + 1)
dp[1] = 1
for i in range(2, n + 1):
dp[i] = dp[i - 1] + dp[i - 2] # ์์ ๋ฌธ์ ๋ถํฐ ์ฐจ๊ทผ์ฐจ๊ทผ ๊ณ์ฐ
return dp[n]
์ต์ ๋ถ๋ถ์งํฉ ์ฑ๋ฆฝ ์์๋ณด๊ธฐ
\(A\) : \(n\)๊ฐ์ ๋ณด์๋ค ์ค ์ต์ ์ผ๋ก ๊ณ ๋ฅธ ๋ถ๋ถ์งํฉ
\(A\)๊ฐ \(n\)๋ฒ์งธ ๋ณด์์ ํฌํจํ๊ณ ์์ง ์๋ค๋ฉด, \(A\)๋ \(n\)๋ฒ์งธ ๋ณด์์ ๋บ ๋๋จธ์ง \(n-1\)๊ฐ์ ๋ณด์๋ค ์ค์์ ์ต์ ์ผ๋ก ๊ณ ๋ฅธ ๋ถ๋ถ์งํฉ๊ณผ ๊ฐ์. \(\to\) ์ต์ ์ ์๋ฆฌ ์ ์ฉ๊ฐ๋ฅ
\(A\)๊ฐ \(n\)๋ฒ์งธ ๋ณด์์ ํฌํจํ๊ณ ์๋ค๋ฉด, \(A\)์ ์ํ ๋ณด์๋ค์ ์ด ๊ฐ๊ฒฉ์ \(n-1\) ๊ฐ์ ๋ณด์๋ค ์ค์์ ์ต์ ์ผ๋ก ๊ณ ๋ฅธ ๊ฐ๊ฒฉ์ ํฉ์๋ค๊ฐ ๋ณด์ \(n\)์ ๊ฐ๊ฒฉ์ ๋ํ ๊ฒ๊ณผ ๊ฐ๋ค.
\(P[i,w]\)๋ i๊ฐ์ ๋ณด์์ด ์๊ณ ๋ฐฐ๋ญ์ ๋ฌด๊ฒ ํ๋๊ฐ w์ผ๋ ์ต์ ์ ์ด์ต
i๋ฒ์งธ ๋ณด์์ด ๋ฐฐ๋ญ์ ๋ฌด๊ฒ ํ๋๋ณด๋ค ๋ฌด๊ฑฐ์ฐ๋ฉด ๋ฃ์์ ์์์ผ๋ก i๋ฒ์งธ ๋ณด์์ ๋บ i-1๊ฐ์ ๋ณด์๋ค์ ๊ฐ์ง๊ณ ๊ตฌํ ์ ๋จ๊ณ์ ์ต์ ๊ฐ์ ์ ์งํ๋ค. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ i๋ฒ์งธ ๋ณด์ใ ๋ฅด ์ํด i๋ฒ์งธ ๋ณด์๋งํผ์ ๋ฌด๊ฒ๋ฅผ ๋น์ ์ ๋์ ์ต์ ๊ฐ์ i๋ฒ์งธ ๋ณด์์ ๊ฐ๊ฒฉ์ ๋ํ ๊ฐ or i-1๊ฐ์ ๋ณด์๋ค์ ๊ฐ์ง๊ณ ๊ตฌํ ์ ๋จ๊ณ์ ์ต์ ๊ฐ์ค max๋ฅผ ์ทจํ๋ค.
12865 : ํ๋ฒํ ๋ฐฐ๋ญ#
์์ฃผ ํด๋์ํ๊ณ ๊ทธ๋ฅ ๋งจ ์ฒ์ ๋ง๋๋ ๋ฐฐ๋ญ ๋ฌธ์ ๋ค. ์ด๋ฆ์ฒ๋ผ ๊ทธ๋๋ ํ๋ฒํ ๋ฐฐ๋ญ ๋ฌธ์ ์ด๋ค. ๋ค๋ฅธ ๋ฐฐ๋ญ ๋ฌธ์ ์งฑ๋ง์ผ๋๊น ๋ฐฑ์ค ๋ฐฐ๋ญ๋ฌธ์ ๋ฌธ์ ์ง ์ฌ๊ธฐ ๋ค์ด๊ฐ์ ๊ตฌ๊ฒฝํด๋ณด์.
import sys
input = sys.stdin.readline
def knapsack(n,k,items):
dp = [[0]*(k+1) for _ in range(n+1)]
for i in range(1,n+1): # ๋ฌผ๊ฑด ๊ฐ์ ๋๋ฆฌ๊ธฐ
w,v = map(int, items[i-1])
for j in range(1,k+1): # ์ต๋๋ฌด๊ฒ ๋๋ฆฌ๊ธฐ
if w <= j: # ๋ฌผ๊ฑด๋ฌด๊ฒ๊ฐ ์ฌ์ ์ฉ๋๋ณด๋ค ์์ผ๋ฉด
dp[i][j] = max(dp[i-1][j], dp[i-1][j-w] + v)
else: # ์ด์ ์ต์ ๊ฐ ์ ์ง
dp[i][j] = dp[i-1][j]
print(dp[n][k])