[Algorithm] Dynamic Programming
๐ฃ
๋ณธ ํฌ์คํธ๋ โ์ด๊ฒ์ด ์ทจ์
์ ์ํ ์ฝ๋ฉ ํ
์คํธ๋ค with ํ์ด์ฌโ์ ๊ณต๋ถํ๊ณ ์์ฑํ์์ต๋๋ค :)
click > (์ด์ฝํ
2021) ์ด๊ฒ์ด ์ทจ์
์ ์ํ ์ฝ๋ฉ ํ
์คํธ๋ค with ํ์ด์ฌ
Dynamic Programming
์ด๋ก
์ฐ๋ฆฌ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๋ ์ฐ์ฐ ์๋์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ต๋ํ์ผ๋ก ํ์ฉํ ์ ์๋ ํจ์จ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ ์์ฑํด์ผ ํ๋ค.
์ด๋ค ๋ฌธ์ ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฝ๊ฐ ๋ ํ์ฉํ๋ฉด ์ฐ์ฐ ์๋๋ฅผ ๋น์ฝ์ ์ผ๋ก ์ฆ๊ฐ์ํฌ ์ ์๋ ๋ฐฉ๋ฒ์ด ์๋ค. ๋ํ์ ์ธ ๋ฐฉ๋ฒ์ด ๋ฐ๋ก ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ (Dynamic Programming) ์ด๋ค. ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ ํฐ ๋ฌธ์ ๋ฅผ ์๊ฒ ๋๋๊ณ , ๊ฐ์ ๋ฌธ์ ๋ผ๋ฉด ํ ๋ฒ์ฉ๋ง ํ์ด ๋ฌธ์ ๋ฅผ ํจ์จ์ ์ผ๋ก ํด๊ฒฐํ๋ ์๊ณ ๋ฆฌ์ฆ ๊ธฐ๋ฒ์ผ๋ก ๋์ ๊ณํ๋ฒ์ด๋ผ๊ณ ํํํ๊ธฐ๋ ํ๋ค.
๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ผ๋ก ํด๊ฒฐํ ์ ์๋ ๋ํ์ ์ธ ์์๋ก ํผ๋ณด๋์น ์์ด๊ณผ ํฉํ ๋ฆฌ์ผ์ด ์๋ค. ๋ ์์ ๋ชจ๋ ์์ด์ ํญ์ ์ ํ์์ ์ด์ฉํ์ฌ ๊ฐ๋จํ๊ฒ ์ ์ํ ์ ์๋ค๋ ํน์ง์ด ์๋ค. ์ ์๋ ๋ ์์๋ฅผ ๋ชจ๋ ์ฌ๊ทํจ์๋ฅผ ์ด์ฉํ์ฌ ๊ตฌํํ์๋๋ฐ, ์ฌ๊ทํจ์๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด n์ด ์ปค์ง ์๋ก ์ํ ์๊ฐ์ด ๊ธฐํ๊ธ์์ ์ผ๋ก ์ฆ๊ฐํ๋ค๋ ๋ฌธ์ ์ ์ด ์๋ค. (์๊ฐ ๋ณต์ก๋๊ฐ ์ฝ O(2^n)์ด๋ค.) ์ด์ฒ๋ผ ์ ํ์์ ์ฌ๊ท ํจ์๋ฅผ ์ฌ์ฉํด ๊ตฌํํ ์๋ ์์ง๋ง, ๋งค๋ฒ ๊ณ์ฐํ๋๋ก ํ๋ค๋ฉด ํจ์จ์ ์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค. ๋ฐ๋ผ์ ์ด๋ฌํ ๋ฌธ์ ๋ ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ ์ฌ์ฉํ์ฌ ํจ์จ์ ์ผ๋ก ํด๊ฒฐํ๋ค. ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ ๋ค์ ์กฐ๊ฑด์ ๋ง์กฑํด์ผ ํ๋ค.
- ํฐ ๋ฌธ์ ๋ฅผ ์์ ๋ฌธ์ ๋ก ๋๋ ์ ์๋ค.
- ์์ ๋ฌธ์ ์์ ๊ตฌํ ์ ๋ต์ ๊ทธ๊ฒ์ ํฌํจํ๋ ํฐ ๋ฌธ์ ์์๋ ๋์ผํ๋ค.
๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ ์ค ํ๋๋ก ๋ฉ๋ชจ์ด์ ์ด์ (Memorization) ๊ธฐ๋ฒ์ด ์๋ค. ๋ฉ๋ชจ์ด์ ์ด์ ๊ธฐ๋ฒ์ ๊ฐ์ ์ ์ฅํ๋ ๋ฐฉ์์ผ๋ก ์บ์ฑ(Caching)์ด๋ผ๊ณ ๋ ํ๋ฉฐ, ํ ๋ฒ ๊ตฌํ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ ์ฅํด๋๊ณ ๊ฐ์ ์์ ๋ค์ ํธ์ถํ๋ฉด ๋ฉ๋ชจํ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋๋ก ๊ฐ์ ธ์ค๋ ๊ธฐ๋ฒ์ ์๋ฏธํ๋ค.
๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์๋ ํฌ๊ฒ 2๊ฐ์ง ๊ตฌํ ๋ฐฉ๋ฒ์ด ์๋ค.
-
ํ๋ค์ด (Top-Down) ๋ฐฉ์
์ฌ๊ทํจ์๋ฅผ ์ด์ฉํ์ฌ ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ ์์ค์ฝ๋๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ํฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์์ ๋ฌธ์ ๋ค์ ํธ์ถํ๋ค๊ณ ํ์ฌ ํ๋ค์ด ๋ฐฉ์์ด๋ผ๊ณ ํ๋ค. ํ๋ค์ด ๋ฐฉ์์ ํํฅ์์ด๋ผ๊ณ ๋ ํ๋ฉฐ ๋ฉ๋ชจ์ด์ ์ด์ ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
ํผ๋ณด๋์น ์์ด ํ๋ค์ด ๋ฐฉ์์ผ๋ก ๊ตฌํ (๋ฉ๋ชจ์ด์ ์ด์ )
# ํ ๋ฒ ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์ (Memoization)ํ๊ธฐ ์ํ ๋ฆฌ์คํธ ์ด๊ธฐํ d = [0] * 100 # ํผ๋ณด๋์น ํจ์(Fibonacci Function)๋ฅผ ์ฌ๊ทํจ์๋ก ๊ตฌํ (ํ๋ค์ด ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ) def fibo(x): # ์ข ๋ฃ ์กฐ๊ฑด(1 ํน์ 2์ผ ๋ 1์ ๋ฐํ) if x == 1 or x == 2: return 1 # ์ด๋ฏธ ๊ณ์ฐํ ์ ์๋ ๋ฌธ์ ๋ผ๋ฉด ๊ทธ๋๋ก ๋ฐํ if d[x] != 0: return d[x] # ์์ง ๊ณ์ฐํ์ง ์์ ๋ฌธ์ ๋ผ๋ฉด ์ ํ์์ ๋ฐ๋ผ์ ํผ๋ณด๋์น ๊ฒฐ๊ณผ ๋ฐํ d[x] = fibo(x - 1) + fibo(x - 2) return d[x] print(fibo(99))
-
๋ณดํ ์ (Bottom-Up) ๋ฐฉ์
๋จ์ํ ๋ฐ๋ณต๋ฌธ์ ์ด์ฉํ์ฌ ์์ค์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ ์์ ๋ฌธ์ ๋ถํฐ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ต์ ๋์ถํ๋ค๊ณ ํ์ฌ ๋ณดํ ์ (Bottom-Up) ๋ฐฉ์์ด๋ผ๊ณ ํ๋ค. ์ฌ๊ทํจ์๋ฅผ ์ฌ์ฉํ๋ ํ๋ค์ด ๋ฐฉ์๋ณด๋ค ์ฑ๋ฅ์ด ๋ ์ข๋ค. ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ ์ ํ์ ์ ํํ๋ ๋ณดํ ์ ๋ฐฉ์์ด๊ณ , ๋ณดํ ์ ๋ฐฉ์์์ ์ฌ์ฉ๋๋ ๊ฒฐ๊ณผ ์ ์ฅ์ฉ ๋ฆฌ์คํธ๋ DP ํ ์ด๋ธ์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
ํผ๋ณด๋์น ์์ด ๋ณดํ ์ ๋ฐฉ์์ผ๋ก ๊ตฌํ
# ์์ ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๊ธฐ ์ํ DP ํ ์ด๋ธ ์ด๊ธฐํ d = [0] * 100 # ์ฒซ ๋ฒ์งธ ํผ๋ณด๋์น ์์ ๋ ๋ฒ์งธ ํผ๋ณด๋์น ์๋ 1 d[1] = 1 d[2] = 1 n = 99 # ํผ๋ณด๋์น ํจ์(Fibonacci Function) ๋ฐ๋ณต๋ฌธ์ผ๋ก ๊ตฌํ(๋ณดํ ์ ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ) for i in range(3, n + 1): d[i] = d[i - 1] + d[i - 2] print(d[n])
๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ ๋ฌธ์ ํ์ด ๋จ๊ณ
- ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ ์ ํ์์ ํ์ ํ๊ธฐ
- ๋ณ์ ๊ฐ ๊ด๊ณ์ ๋ง๋ค๊ธฐ(์ ํ์)
- ๊ตฌํํ๊ธฐ(memoization or tabulation)
์ค์ ๋ฌธ์
[์ค์ ๋ฌธ์ 1] 1๋ก ๋ง๋ค๊ธฐ
# ์ ์ X๋ฅผ ์
๋ ฅ ๋ฐ๊ธฐ
x = int(input())
# ์์ ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๊ธฐ ์ํ DP ํ
์ด๋ธ ์ด๊ธฐํ
d = [0] * 1000001
# ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ(Dynamic Programming) ์งํ(๋ณดํ
์
)
for i in range(2, x + 1):
# ํ์ฌ์ ์์์ 1์ ๋นผ๋ ๊ฒฝ์ฐ
d[i] = d[i - 1] + 1
# ํ์ฌ์ ์๊ฐ 2๋ก ๋๋์ด ๋จ์ด์ง๋ ๊ฒฝ์ฐ
if i % 2 == 0:
d[i] = min(d[i], d[i // 2] + 1)
# ํ์ฌ์ ์๊ฐ 3์ผ๋ก ๋๋์ด ๋จ์ด์ง๋ ๊ฒฝ์ฐ
if i % 3 == 0:
d[i] = min(d[i], d[i // 3] + 1)
# ํ์ฌ์ ์๊ฐ 5๋ก ๋๋์ด ๋จ์ด์ง๋ ๊ฒฝ์ฐ
if i % 5 == 0:
d[i] = min(d[i], d[i // 5] + 1)
print(d[x])
[์ค์ ๋ฌธ์ 2] ๊ฐ๋ฏธ ์ ์ฌ
# ์ ์ N์ ์
๋ ฅ ๋ฐ๊ธฐ
n = int(input())
# ๋ชจ๋ ์๋ ์ ๋ณด ์
๋ ฅ ๋ฐ๊ธฐ
array = list(map(int, input().split()))
# ์์ ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๊ธฐ ์ํ DP ํ
์ด๋ธ ์ด๊ธฐํ
d = [0] * 100
# ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ(Dynamic Programming) ์งํ (๋ณดํ
์
)
d[0] = array[0]
d[1] = max(array[0], array[1])
for i in range(2, n):
d[i] = max(d[i - 1], d[i - 2] + array[i])
# ๊ณ์ฐ๋ ๊ฒฐ๊ณผ ์ถ๋ ฅ
print(d[n - 1])
[์ค์ ๋ฌธ์ 3] ๋ฐ๋ฅ ๊ณต์ฌ
# ์ ์ N์ ์
๋ ฅ ๋ฐ๊ธฐ
n = int(input())
# ์์ ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๊ธฐ ์ํ DP ํ
์ด๋ธ ์ด๊ธฐํ
d = [0] * 1001
# ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ(Dynamic Programming) ์งํ (๋ณดํ
์
)
d[1] = 1
d[2] = 3
for i in range(3, n + 1):
d[i] = (d[i - 1] + 2 * d[i - 2]) % 796796
# ๊ณ์ฐ๋ ๊ฒฐ๊ณผ ์ถ๋ ฅ
print(d[n])
๋๊ธ๋จ๊ธฐ๊ธฐ