intro
๐ฅ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ ํ ์ฌ์ฉํ์ฌ ์ํ ์๊ฐ ํจ์จ์ฑ์ ๋น์ฝ์ ์ผ๋ก ํฅ์. ์ด๋ฏธ ๊ณ์ฐ๋ ๊ฒฐ๊ณผ(์์ ๋ฌธ์ )๋ ๋ณ๋์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ ์ฅํ์ฌ ๋ค์ ๊ณ์ฐํ์ง ์๋๋ก ํจ. ๋ฐ๋ผ์ ์์ ํ์์ ๋นํจ์จ์ ์ธ ์๊ฐ ๋ณต์ก๋ ์ฑ๋ฅ ํ๊ณ์ ์ ํด๊ฒฐํด์ค๋ค. ๋ํ '๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ = ๋์ ๊ณํ๋ฒ'์ด๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค. (๋์ (dynamic) ํ ๋น(allocation) - 'ํ๋ก๊ทธ๋จ์ด ์คํ๋๋ ๋์ค์ ์คํ์ ํ์ํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๋ ๊ธฐ๋ฒ'). DP ์๊ณ ๋ฆฌ์ฆ์ ํ์ฉํ๋ค๋ฉด ์ฌ๋ฌ sub-problem ํฌํจ ๋ชจ๋ ๋ฌธ์ ์ ์ ๋ต์ด ๋ค์ด๊ฐ๋ ๋ฉ๋ชจ๋ฆฌ ๋ฏธ๋ฆฌ ๋ฐฐ์น(์ด ๋ ์ฌ๋ฌ ๋ฌธ์ ๋ค์ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๋ ์ ์ฅ์ฉ list๋ dp-table). DP ์๊ณ ๋ฆฌ์ฆ์ ํ์ฉํ๊ธฐ ์ํด์๋ ์๋ ๋๊ฐ์ง ์กฐ๊ฑด์ ๋ง์กฑํด์ผ ํ๋ค.
โ ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ(Optimal Substructure) - ํฐ ๋ฌธ์ ๋ฅผ ์์ ๋ฌธ์ ๋ก ๋๋ ์ ์์ผ๋ฉฐ, ์์ ๋ฌธ์ ์ ๋ต์ ๋ชจ์์ ํฐ ๋ฌธ์ ํด๊ฒฐ
โก ์ค๋ณต๋๋ ๋ถ๋ถ ๋ฌธ์ (Overlapping Subproblem) - ๋์ผํ ์์ ๋ฌธ์ ๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ํด๊ฒฐ
๐ฅ ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ ๊ตฌํ์ ์ผ๋ฐ์ ์ผ๋ก ๋ ๊ฐ์ง ๋ฐฉ์ → top-down(์์์ ์๋-ํํฅ์) & bottom-up(์๋์์ ์-์ํฅ์)์ผ๋ก ๊ตฌ์ฑ๋๋ค.
โ top-down (ํํฅ์) : memoization
: dp ๊ตฌํ๋ฒ ์ค ํ๋๋ก, ํ ๋ฒ ๊ณ์ฐํ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ(ํ ์ด๋ธ, ์บ์, dp)์ ๋ฉ๋ชจ ํ๋ ๊ธฐ๋ฒ์ด๋ค. ์ฆ, ๊ฐ์ ๋ฌธ์ ๋ฅผ ๋ค์ ํธ์ถํ๋ฉด ๋ฉ๋ชจํ๋ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋๋ก ๊ฐ์ ธ์ค๊ณ , ๊ฐ์ ๊ธฐ๋กํด ๋๋๋ค๋ ์ ์์ caching์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค. ํฐ ๋ฌธ์ ๋ฅผ ์๊ฒ ๋๋์ด ํธ๋ ๋ฐฉ์์ผ๋ก ์ฃผ๋ก ์ฌ๊ท๊ฐ ์ฌ์ฉ(์ด ๊ณผ์ ์์ ํ๋ฒ ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ ๊ธฐ๋กํ๋ ๋ฉ๋ชจ์ด์ ์ด์ ์งํ. ์ฆ, ๋ฉ๋ชจ์ด์ ์ด์ ์ด๋, ์ด์ ์ ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ฅผ ์ผ์์ ์ผ๋ก ๊ธฐ๋กํด ๋๋ ๊ฐ๋ ์ ๋ปํ๋ค์ฌ๊ธฐ์ ๋ฉ๋ชจ์ด์ ์ด์ ์ด๋ ํ ๋ฒ ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ด์ ๋๊ธฐ๋ง ํ๊ณ dp๋ฅผ ์ํด ํ์ฉํ์ง๋ ์์ ์๋ ์์ผ๋ฏ๋ก ์๋ฐํ ๋งํ๋ฉด ๋ฉ๋ชจ์ด์ ์ด์ ๊ณผ dp๋ ๊ฐ์ ๊ฐ๋ ์ด ์๋๋ค. ํผ๋ํ์ง ๋ง์.
โก bottom-up (์ํฅ์) : tabulation
: ์๋์ชฝ์์ ์์ ๋ฌธ์ ๋ฅผ ๋จผ์ ์ฐจ๊ทผ์ฐจ๊ทผ ํด๊ฒฐํด๋๊ฐ๋ฉด์ ๊ทธ ๋ค์์ ๋ฌธ์ ๊น์ง ์ฐจ๋ก๋ก ํด๊ฒฐํด ๋๊ฐ๋ ๊ณผ์ ์ ๋ปํ๋ค. ๋ฐ๋ณต๋ฌธ์ ์ฃผ๋ก ์ฌ์ฉํ๋ฉฐ, dp์์ ๊ฐ์ฅ ๋ง์ด ๊ตฌํํ๋ ๋ฐฉ์์ด๋ค. ์ฆ '์ฌ๋ฌ ๊ฐ์ ํ์ ๋ฌธ์ ๋ฅผ ๋จผ์ ํผ ํ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์์์ฌ๋ ค ์ฃผ์ด์ง ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์๊ณ ๋ฆฌ์ฆ'์ด๋ค. ๋ฌธ์ ํด๊ฒฐ์ ์ํ ์ ํ์์ ์ฐพ์๋ธ ํ, ์ ํ์์ ํญ์ ๋ฐ์์๋ถํฐ ์ฐจ๋ก๋ก ๊ตฌํด๋๊ฐ์ ๋ต์ ์์๋ด๋ ํํ์ ์๊ณ ๋ฆฌ์ฆ
ex - fibonacci
๐ฅ ํผ๋ณด๋์น๋ 1,1,2,3,5,8,13,21,34,55,89, .... ์ ๊ฐ์ ์์ด์ด๋ค. ์ ํ์์ $a_n = a_{n-1} + a_{n-2}, a_1 = 1, a_2 = 1$ n๋ฒ์งธ fibonacci ์๋ฅผ f(n)์ด๋ผ๊ณ ํ ๋ 4๋ฒ์งธ fibonacci ์ $f(4)$๋ฅผ ๊ตฌํ๋ ๊ณผ์ ์ ์๋์ ๊ฐ๋ค. ์ด ๋ fibonacci ์๋ ์ฌ๋ฌ๊ฐ์ f(n)๋ก ๋๋์ด์ง๋ฏ๋ก โ ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ ์กฐ๊ฑด์ ๋ง์กฑ. ์๋ ์ค๋ฅธ์ชฝ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ๋์ผํ f๊ฐ ์ฌ๋ฌ ๋ฒ ๋ฐ๋ณต์ ์ผ๋ก ์ฌ์ฉ. ๋ฐ๋ผ์ โก ์ค๋ณต๋๋ ๋ถ๋ถ ์กฐ๊ฑด๋ ๋ง์กฑ. ์๋ฅผ ๋ค์ด f(6)์ ๊ตฌํ๋ ๊ณผ์ ์์ f(2)๊ฐ ์ฌ๋ฌ ๋ฒ ํธ์ถ๋๋ค. ๋ฐ๋ผ์ dp๋ฅผ ์ฌ์ฉํด ์ฌ๋ฌ๋ฒ ํธ์ถ๋๋ f(2)๋ฅผ ํ ๋ฒ๋ง ๊ณ์ฐํด์ ๋ณ๋ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํด ์ดํ f(2)๊ฐ ๊ณ์ ๊ณ์ฐ๋๋ ๋ญ๋น๋ฅผ ๋ง์ ์ ์๋ค.
๐ฅ ์๋ฅผ ๋ค์ด f(99)๋ฅผ ๊ตฌํ๋ค๊ณ ํ์ ๋ ์๋์ ๊ฐ์ด ๋ ๊ฐ์ง ๋ฐฉ์์ ์ฌ์ฉํ ์ ์๋ค.
โ top-down ๋ฐฉ์(memoization) - ์ฌ๊ท์ฌ์ฉ, ํจ์ ์ข ๋ฃ ์กฐ๊ฑด
#dp-table initialization
d=[0]*100
#fibonacci recursive function (top-down dp)
def fibo(x):
#exit
if x==1 or x==2: return 1
#if sub-problem already solved, get the answer
if d[x]!=0:return d[x]
#if not solved, add the results
d[x]=fibo(x-1)+fibo(x-2)
return d[x]
print(fibo(99))#218922995834555169026
: ๋ฉ๋ชจ์ด์ ์ด์ ๊ฒฐ๊ณผ ์ ์์น ๋ ๋ ธ๋๋ง ๋ฐฉ๋ฌธ๋จ์ ํ์ธํ ์ ์๋ค. ๋ฐ๋ผ์ ๋ฉ๋ชจ์ด์ ์ด์ ๊ธฐ๋ฒ ์ฌ์ฉ ์ fibonacci ์์ด ํจ์์ ์๊ฐ ๋ณต์ก๋๋ O(N) ํผ๋ณด๋์น ์์ด์ ์ง์ ํํ ์๊ฐ ๋ณต์ก๋๋ฅผ ์ ํ ์๊ฐ ๋ณต์ก๋๋ก ์ค์ผ ์ ์๋ค.
โก bottom-up ๋ฐฉ์(tabulation) - ๋ฐ๋ณต๋ฌธ ์ฌ์ฉ, ์ฒซ ํญ ์ค์
d=[0]*100
d[1],d[2]=1,1
n=99
#bottom-up dp
for i in range(3,n+1):
d[i]=d[i-1]+d[i-2]
print(d[n]) #218922995834555169026
dp vs divide-conquer
๐ฅ dp์ ๋ถํ ์ ๋ณต ์๊ณ ๋ฆฌ์ฆ ๋ชจ๋ ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ๋ ์ฌ์ฉํ ์ ์๋ค(์ ์กฐ๊ฑด โ ). ์ฆ, ํฐ ๋ฌธ์ ๋ฅผ ์์ ๋ฌธ์ ๋ก ๋๋ ์ ์์ผ๋ฉฐ ์์ ๋ฌธ์ ์ ๋ต์ ๋ชจ์์ ํฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ์ํฉ์ด๋ผ๋ฉด dp ๋๋ ๋ถํ ์ ๋ณต์ ์ฌ์ฉํ ์ ์๋ ์กฐ๊ฑด ์ถฉ์กฑ. ๊ทธ๋ฌ๋ dp๋ฌธ์ ์์๋ ๊ฐ ๋ถ๋ถ ๋ฌธ์ ๋ค์ด ์๋ก ์ํฅ์ ๋ฏธ์น๋ฉฐ ๋ถ๋ถ ๋ฌธ์ ๊ฐ ์ค๋ณต๋๋ค(์ ์กฐ๊ฑดโก) / ๊ทธ๋ฌ๋ ๋ถํ ์ ๋ณต ๋ฌธ์ ๋ ๋์ผํ ๋ถ๋ถ ๋ฌธ์ ๊ฐ ๋ฐ๋ณต์ ์ผ๋ก ๊ณ์ฐ๋์ง ์๋๋ค. ์ฌ๋ฌ ๋ถํ ๋ฌธ์ ๋ ์๋ก ๋ณ๊ฐ์ด๋ค. ์๋ฅผ ๋ค์ด ๋ถํ ์ ๋ณต ๋ํ ๋ฌธ์ ์ธ quick sort ๋ฌธ์ ๋, ํ ๋ฒ ๊ธฐ์ค ์์(pivot)๊ฐ ์๋ฆฌ๋ฅผ ๋ณ๊ฒฝํด์ ์๋ฆฌ๋ฅผ ์ก์ผ๋ฉด, ํด๋น ์์์ ์์น๋ ๋ฐ๋์ง ์๋๋ค. ๋ฐ๋ผ์ ๋ถํ ์ดํ ํด๋น pivot์ ๋ค์ ์ฒ๋ฆฌํ๋ ๋ถ๋ถ ๋ฌธ์ ๋ ํธ์ถํ์ง ์๋๋ค. ํ์ง๋ง dp๋ ์ฌ๋ฌ sub-problem์ ๊ฒฐ๊ณผ๋ก ๋ค๋ฅธ sub-problem ํด๊ฒฐ์ ์ค๋ง๋ฆฌ๊ฐ ๋๋ค. ๋ฐ๋ผ์ dp ๋ฌธ์ ๋ฅผ ํ๊ธฐ ์ํ ์ ๊ทผ ์์๋ ์๋์ ๊ฐ๋ค.
โ ์ฃผ์ด์ง ๋ฌธ์ ๊ฐ dp ์ ํ์์ ํ์ - ์ต์ ๋ถ๋ถ๊ตฌ์กฐ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์ง / ์ค๋ณต๋๋ ๋ถ๋ถ ๋ฌธ์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์ง. ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ฆฌ๋ / ๊ตฌํ / ์์ ํ์ ๋ฑ์ ์์ด๋์ด๋ก ๋จผ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ์ง ๊ฒํ
โก dp-table initialization
โข ๊ฐ ํญ๊ณผ์ ๊ด๊ณ ์ ํ์์ ์ฐพ๊ธฐ
โฃ ์ด๊น๊ฐ ์ ์: ์ผ๋ฐ์ ์ผ๋ก bottom-up ๋ฐฉ์์ dp์ ํ์ด ๋ง์ด ์ถ์ ๋๋ฏ๋ก ์ด๊น๊ฐ์ ์ ์ ํ ์ ์ํ ๋ค์ ์๋์์ ์๋ก ์ฌ๋ผ๊ฐ๋ฉฐ ๊ฐ์ ์ญ ๊ตฌํด๋๊ฐ๋ฉด ๋๋ค.
dp - memoization vs recursion
# Python program to find
# fibonacci number using memoization.
def fibRec(n, memo):
# Base case
if n <= 1:
return n
# To check if output already exists
if memo[n] != -1:
return memo[n]
# Calculate and save output for future use
memo[n] = fibRec(n - 1, memo) + \
fibRec(n - 2, memo)
return memo[n]
def fib(n):
memo = [-1] * (n + 1)
return fibRec(n, memo)
n = 5
print(fib(n))
: dp-memoization ๊ธฐ๋ฒ์ recursion๊ณผ ๋ค๋ฅด๋ค. recursion ๊ธฐ๋ฒ์ด ์ฐ์์ ๋ฟ, recursion ์๊ณ ๋ฆฌ์ฆ ์์ฒด๋ฅผ dp-memoization ๊ธฐ๋ฒ์ด๋ผ ํ ์ ์๋ค. recursion์ผ๋ก ์ฌ๊ท๋ฅผ ์งํํ๋ฉฐ ๋์ค์ ์ ๋ฐ์ดํธ ์๋ ์นธ์ด ์๋ค๋ฉด, ํด๋น ์นธ๋ง ์ฌ๊ท์ ์ผ๋ก ์งํํ ๋ฟ, ์ ๋ฐ์ดํธ ๋ ์นธ์ memoization ๊ธฐ๋ฒ์ผ๋ก ๊ธฐ์ตํด ๋์ ์นธ์ ๋ด์ฉ์ ๋ฐ๋ก ์ฌ์ฉ(์ ์์ ์ฝ๋์์ ๋ฐ๋ก return).
dp vs greedy
๐ฅ dp์ greedy ๋ชจ๋ ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ ๋ฌธ์ ๋ก ๋ถ๋ถ์ ์ผ๋ก ์ ํํ ๋ฌธ์ ์ ์ต์ ํด์ ์ด์ด์ ๊ณ์ํด ๋ ํฐ ๋ฌธ์ ์ ์ต์ ํด๋ฅผ ๊ตฌํ๋ค๋ ์ ์์ ๋์ผ.
(1) ํ์ง๋ง, greedy๋ ๋น์ฅ ํ์์ ์ผ๋ก ์ ํํ ๋ถ๋ถ์ด ์ ์ฒด ๋ฌธ์ ์ ์ต์ ํด๋ฅผ ๋ณด์ฅํ์ง๋ง, dp ๊ธฐ๋ฒ์ผ๋ก๋ ๊ทธ๋ ์ง ์๋ค. ์๋ฅผ ๋ค์ด 16์์ด ์๊ณ , ๋์ ๋จ์๊ฐ 10, 7, 3์์ด ์๋ค๋ฉด ๋น์ฅ 10์๋ถํฐ ์ ํํ๋๊ฒ ์ ์ฒด์ greedy ๋ณด์ฅ. ํ์ง๋ง, 10, 8, 6์์ด ์๋ค๋ฉด ๋น์ฅ 10์๋ถํฐ ์ ํํ๋๊ฒ ์ ์ฒด์ greedy ๋ณด์ฅ์ด๋ผ ๋งํ ์ ์๋ค. ๋ฐ๋ผ์ greedy choice property๋ฅผ ๋ง์กฑํ๋ ์ง ํ์ง ์๋ ์ง greedy๋ ๋ง์กฑํด์ผ ํ๋ฉฐ, dp๋ ๊ทธ๋ ์ง ์๋ค.
(2) ๋ํ, dp๋ ๊ฐ sub-problem๋ค์ด ์๋ก overlapping ๋๋ ์ฑ์ง์ ๋ง์กฑํด์ผ ํ๋ค. ์๋ฅผ ๋ค์ด dp๋ ์ ํ์์ผ๋ก ๋ํ๋ผ ์ ์๊ณ , dp[x] = dp[x-1] + dp[x-2]์ ๊ฐ์ด dp[x]๋ผ๋ ๋ฌธ์ ์์ฒด๊ฐ dp[x-1]๊ณผ dp[x-2]์ ์ผ๋ถ์ overlapping๋์ด ๋ง์กฑํ๋ค.
dp exercises
Q. ๊ฐ๋ฏธ ์ ์ฌ
Q. ๊ฐ๋ฏธ ์ ์ฌ๋ ๋ถ์กฑํ ์๋์ ์ถฉ๋นํ๊ณ ์ ๋ฉ๋๊ธฐ ๋ง์์ ์๋ ์ฐฝ๊ณ ๋ฅผ ๋ชฐ๋ ๊ณต๊ฒฉํ๋ ค๊ณ ํฉ๋๋ค. ๋ฉ๋๊ธฐ ๋ง์์๋ ์ฌ๋ฌ ๊ฐ์ ์๋์ฐฝ๊ณ ๊ฐ ์๋๋ฐ ์๋์ฐฝ๊ณ ๋ ์ผ์ง์ ์ผ๋ก ์ด์ด์ ธ ์์ต๋๋ค. ๊ฐ ์๋ ์ฐฝ๊ณ ์๋ ์ ํด์ง ์์ ์๋์ ์ ์ฅํ๊ณ ์์ผ๋ฉฐ ๊ฐ๋ฏธ ์ ์ฌ๋ ์๋์ฐฝ๊ณ ๋ฅผ ์ ํ์ ์ผ๋ก ์ฝํํ์ฌ ์๋์ ๋นผ์์ ์์ ์ ๋๋ค. ์ด ๋ ๋ฉ๋๊ธฐ ์ ์ฐฐ๋ณ๋ค์ ์ผ์ง์ ์์ ์กด์ฌํ๋ ์๋์ฐฝ๊ณ ์ค์์ ์๋ก ์ธ์ ํ ์๋์ฐฝ๊ณ ๊ฐ ๊ณต๊ฒฉ๋ฐ์ผ๋ฉด ๋ฐ๋ก ์์์ฑ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๊ฐ๋ฏธ ์ ์ฌ๊ฐ ์ ์ฐฐ๋ณ์๊ฒ ๋คํค์ง ์๊ณ ์๋์ฐฝ๊ณ ๋ฅผ ์ฝํํ๊ธฐ ์ํด์๋ ์ต์ํ ํ ์นธ ์ด์ ๋จ์ด์ง ์๋์ฐฝ๊ณ ๋ฅผ ์ฝํํด์ผ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด ์๋์ฐฝ๊ณ 4๊ฐ๊ฐ ๋ค์๊ณผ ๊ฐ์ด ์กด์ฌํ๋ค๊ณ ๊ฐ์ ํฉ์๋ค. {1,3,1,5}
์ด ๋ ๊ฐ๋ฏธ ์ ์ฌ๋ ๋ ๋ฒ์งธ ์๋์ฐฝ๊ณ ์ ๋ค ๋ฒ์งธ ์๋์ฐฝ๊ณ ๋ฅผ ์ ํํ์ ๋ ์ต๋๊ฐ์ธ ์ด 8๊ฐ์ ์๋์ ๋นผ์์ ์ ์์ต๋๋ค. ๊ฐ๋ฏธ ์ ์ฌ๋ ์๋์ฐฝ๊ณ ๊ฐ ์ด๋ ๊ฒ ์ผ์ง์ ์์ผ ๋ ์ต๋ํ ๋ง์ ์๋์ ์ป๊ธฐ๋ฅผ ์ํฉ๋๋ค. ๊ฐ๋ฏธ ์ ์ฌ๋ฅผ ์ํด ์๋์ฐฝ๊ณ N๊ฐ์ ๋ํ ์ ๋ณด๊ฐ ์ฃผ์ด์ก์ ๋ ์ป์ ์ ์๋ ์๋์ ์ต๋๊ฐ์ ๊ตฌํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ์ธ์.
#my answer
N=int(input())
counts=list(map(int,input().split()))
an=[0]*N #dp-table initialization
for n in range(N):
if n==0: an[0] = counts[n]
elif n==1: an[1] = max(an[0],counts[n])
else:
an[n] = max(an[n-1],an[n-2]+counts[n]) #an
print(an[-1])
#answer
n=int(input())
array=list(map(int,input().split()))
#dp-table initialization
d = [0]*100
#bottom-up dp
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])
๐ฅ ๋ฌธ์ ์ ์ํด, ๊ฐ ์ฐฝ๊ณ ๋ณ๋ก ์ต๋๋ก ํธ ์ ์๋ ์๋์ ๊ฐ์๋ฅผ a(n)์ด๋ผ๊ณ ํ์. ๊ทธ๋ ๋ค๋ฉด n๋ฒ์งธ ์๋ ์ฐฝ๊ณ ์์ ์๋ ๋ ๊ฐ์ง ๊ฒฝ์ฐ์ ์ ์ค ์ต๋๊ฐ์ a(n)
a(n) = max(a(n-1), a(n-2)+n)
๐ฅ ์ ๋ฌธ์ ๋ dp๋ฌธ์ ๋ก ๋ ๊ฐ์ง dp ์กฐ๊ฑด์ ๋ง์กฑํ๋ค. โ ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ - ์์ ๋๊ฐ์ง ๊ฒฝ์ฐ์ ๋ํด์๋ง ์ต์ ์ ์๋ฃจ์ ์ ๊ตฌํ๋ฏ๋ก ์ฑ๋ฆฝ / โก ์ค๋ณต๋๋ ๋ถ๋ถ ๊ตฌ์กฐ - ์ ์ ํ์ ์์ด์ ์ํด ๊ณ์ a(n)์ ํธ์ถํ ๋ ์์์ ๊ณ ๋ ค๋ a(n-1)๊ณผ a(n-2)๊ฐ ์ค๋ณต์ผ๋ก ๊ณ ๋ ค๋๋ฏ๋ก ์กฐ๊ฑด ์ฑ๋ฆฝ. ๋ํ ์ด๋ bottom-up ์ํฅ์ dp ๋ฌธ์ ๋ก ํ ์ ์๋ค. a[0]์ผ๋๋ถํฐ ์ต์ข a[n]๊น์ง ๊ณ์ ์์ด ์ฐ์ฐ์ ์งํํ๊ธฐ ๋๋ฌธ์ bottom-up ์ํฅ์ dp ๊ตฌ์กฐ ๋ฌธ์ . ์ด๋ ๊ฒ dp๋ฌธ์ ๋ ๋ฌธ์ ์ํฉ์ ๋ง๊ฒ ์ ํ์์ ์ธ์ด ๋ค, bottom-up ๋ฐฉ์์ผ๋ก ์ต์ข ์์ด๊ฐ a(n)์ ์๋กญ๊ฒ ๋ง๋ dp-table์์ ๊ตฌํ๋ ์ ํ์ด ๋งค์ฐ ๋น๋ฒํ ๋ฑ์ฅํ๋ฏ๋ก ๊ธฐ์ต
Q. 1๋ก ๋ง๋ค๊ธฐ
Q. ์ ์ X๊ฐ ์ฃผ์ด์ก์ ๋, ์ ์ X์ ์ฌ์ฉํ ์ ์๋ ์ฐ์ฐ์ ๋ค์๊ณผ ๊ฐ์ด 4๊ฐ์ง์ ๋๋ค. (1) X๊ฐ 5๋ก ๋๋์ด ๋จ์ด์ง๋ฉด, 5๋ก ๋๋๋๋ค. (2) X๊ฐ 3์ผ๋ก ๋๋์ด ๋จ์ด์ง๋ฉด, 3์ผ๋ก ๋๋๋๋ค. (3) X๊ฐ 2๋ก ๋๋์ด ๋จ์ด์ง๋ฉด, 2๋ก ๋๋๋๋ค. (4) X์์ 1์ ๋บ๋๋ค.
์ ์ X๊ฐ ์ฃผ์ด์ก์ ๋, ์ฐ์ฐ 4๊ฐ๋ฅผ ์ ์ ํ ์ฌ์ฉํด์ ๊ฐ์ 1๋ก ๋ง๋ค๊ณ ์ ํฉ๋๋ค. ์ฐ์ฐ์ ์ฌ์ฉํ๋ ํ์์ ์ต์๊ฐ์ ์ถ๋ ฅํ์ธ์. ์๋ฅผ ๋ค์ด ์ ์๊ฐ 26์ด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๊ณ์ฐํด์ 3๋ฒ์ ์ฐ์ฐ์ด ์ต์๊ฐ์ ๋๋ค.
26 → 25 → 5 → 1
#bottom-up dp
n=int(input())
if n==1:print(0)
elif n==2 or n==3:print(1)
elif n==4:print(2)
else:
dp=[0]*(n+1)
dp[2],dp[3],dp[5]=1,1,1
cnt=0
for i in range(4,n+1):
a,b,c,d=30001,30001,30001,30001
if i%5==0:
a=dp[i//5]
if i%3==0:
b=dp[i//5]
if i%2==0:
c=dp[i//2]
d=dp[i-1]
dp[i]=min(a,b,c,d)+1
print(dp[n])
๐ฅ ์ด ๋ฌธ์ ๋ dp์ ๋๊ฐ์ง ์กฐ๊ฑด(์ต์ ๋ถ๋ถ๊ตฌ์กฐ, ์ค๋ณต๋๋ ๋ถ๋ถ)์ ๋ชจ๋ ๋ง์กฑํ๋ค. ์ค์ํ ๊ฑด, greedy ์ ํ๊ณผ๋ ๋ค๋ฅด๋ค๋ ์ ! greedy์ ๊ฒฝ์ฐ ๊ทธ ์ด๋ค ์ํฉ์ด์ด๋ 5๋ก ๋๋๋ ๊ฒฝ์ฐ๊ฐ 1์ ๋นผ๋ ๊ฒฝ์ฐ๋ณด๋ค ๋งค ์ํฉ์์ ์ฐ์ ์๋์ด์ผ ํ๋๋ฐ, ํด๋น ๋ฌธ์ ๋ 1์ ๋จผ์ ๋นผ๊ณ ๋ ๋ค์์ ์ฐ์ฐ ๊ฒฐ๊ณผ๊ฐ ๋จผ์ 5๋ก ๋๋๋ ๊ฒฝ์ฐ์ ๊ฒฐ๊ณผ๋ณด๋ค ๋ ์ต์ ์ผ ์ ์์ผ๋ฏ๋ก greedy๋ฅผ ์ ์ฉํ ์ ์๋ค. greedy ์ ํ์ ์ฌ๋ฌ ์ํฉ์ด ์ฃผ์ด์ก์ ๋ ์ต์ ์ ๊ฒฐ๊ณผ๋ฅผ ๋ด๊ธฐ ์ํด ๋ฐ๋์ ์ํฉ์ ์ฐ์ ์์๊ฐ ์กด์ฌํ ๋ ์ธ ์ ์์ ์ ํ์์ ์ธ์๋ณด๋ฉด, a(i)๋ฅผ 1๋ก ๋ง๋ค๊ธฐ ์ํ ์ต์ ์ฐ์ฐ ํ์๋ผ ์ ์ํ์ ๋,
a(i) = min(a(i-1), a(i/2), a(i/3), a(i/5)+1)
(๋จ, 1์ ๋นผ๋ ์ฐ์ฐ์ ์ ์ธํ๊ณ ๋ ํด๋น ์๋ก ๋๋์ด ๋จ์ด์ง ๋์ ํํด ์ ํ์ ์ ์ฉ ๊ฐ๋ฅ)
x=int(input())
d=[0]*30001
for i in range(2,x+1):
d[i]=d[i-1]+1
if i%2==0:d[i] = min(d[i],d[i//2]+1)
if i%3==0:d[i] = min(d[i],d[i//3]+1)
if i%5==0:d[i] = min(d[i],d[i//5]+1)
print(d[x])
Q. ํจ์จ์ ์ธ ํํ ๊ตฌ์ฑ
Q. N๊ฐ์ง ์ข ๋ฅ์ ํํ๊ฐ ์์ต๋๋ค. ์ด ํํ๋ค์ ๊ฐ์๋ฅผ ์ต์ํ์ผ๋ก ์ด์ฉํด์ ๊ทธ ๊ฐ์น์ ํฉ์ด M์์ด ๋๋๋ก ํ๋ ค๊ณ ํฉ๋๋ค. ์ด ๋ ๊ฐ ์ข ๋ฅ์ ํํ๋ ๋ช ๊ฐ๋ผ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด 2์, 3์ ๋จ์์ ํํ๊ฐ ์์ ๋๋ 15์์ ๋ง๋ค๊ธฐ ์ํด 3์์ 5๊ฐ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ต์ํ์ ํํ ๊ฐ์์ ๋๋ค. M์์ ๋ง๋ค๊ธฐ ์ํ ์ต์ํ์ ํํ ๊ฐ์๋ฅผ ์ถ๋ ฅํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ์ธ์.
๐ฅ ์ ํ์ idea: ๋ง๋ค ์ ์๋ ๊ธ์ก์์, ๋ ํํ ์ข ๋ฅ 2์ 3์ด ์๋ค๊ณ ํ ๋, 5๋ฅผ 2์ 3์ผ๋ก ๋ง๋ค ์ ์๋ ์ต์ ๊ฐ์ง์๋ ํ์ฌ ์์น์์ 2์ 3์ ๋บ ๊ฐ๊ฐ์ ์ต์๊ฐ์ 1์ ๋ํ ๊ฒฐ๊ณผ์ด๋ค. ์ฆ, ํ์ฌ ๊ธ์ก์์ ํํ ๋จ์๋ฅผ ๊ฐ๊ฐ ๋บ ๊ฒฝ์ฐ์ dp table ๊ฐ์ ์ต์๊ฐ์์ 1์ ๋ํ ๊ฒฐ๊ณผ๊ฐ ํํ ๋จ์๋ก ๋ง๋ค ์ ์๋ ์ต์ ๊ฐ์ง์๋ก dp-table์ updateํ ์ ์๋ค.
N,M=map(int,input().split())
dp=[M+1]*(M+1)
coins=[]
i=0
for _ in range(N):
coin=int(input())
coins.append(coin)
i=coin
if coin<=M:dp[coin]=1
#dp-table initialization from i+1
for cur_coin in range(i+1,M+1):
cur_min=M+1
for c in coins:
if cur_min>dp[cur_coin-c]:
cur_min=dp[cur_coin-c]
dp[cur_coin]=cur_min+1
print(dp)
print(-1 if dp[-1]>M else dp[-1])
๐ฅ ๋จผ์ ํํ๋จ์์ ํด๋นํ๋ dp table ์นธ์ 1 ๋ฐฐ์น. ๊ทธ๋ฆฌ๊ณ i+1(ํํ ๋จ์ ์ต๋๊ฐ+1)๋ถํฐ ๋ณธ๊ฒฉ์ ์ผ๋ก dp table ์งํ ์์ํ๋ค. ๋ฐ๋ณต๋ฌธ์ผ๋ก ํ์ฌ ๊ธ์ก์์ ๊ฐ๊ฐ ํํ ๋จ์๋ฅผ ๋บ ๊ฒฝ์ฐ ์ค ์ต์๊ฐ์ ์ฐพ์๋ค๋ฉด, ํด๋น ์ต์๊ฐ์์ 1์ ๋ํ ๊ฐ์ dp table์ ์ ๋ฐ์ดํธํ๋ค. inf๊ฐ ๋์์ผ๋ฉด ํํ๋จ์๋ก ๊ณ์ฐํ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ์๋ค๋ ๋ป์ด๋ฏ๋ก -1 ์ถ๋ ฅ, ๊ทธ๋ ์ง ์๋ค๋ฉด ์ต์ข ๊ฐ ์ถ๋ ฅ. a(i)๋ฅผ ๊ธ์ก i๋ฅผ ๋ง๋ค ์ ์๋ ์ต์ํ์ ํํ ๊ฐ์๋ผ๊ณ ํ์. ์ ํ์์ ๊ฐ ํํ ๋จ์์ธ k๋ฅผ ํ๋์ฉ ํ์ธํ๋ฉฐ a(i-k)๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ด ์กด์ฌํ๋ค๋ฉด a(i) = min(a(i), a(i-k)+1). ๊ทธ๋ฆฌ๊ณ a(i-k)๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ด ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ๋ a(i-k) = ∞ ์ค์
n,m=map(int,input().split())
array=[]
for i in range(n):array.append(int(input()))
#dp table
d=[10001]*(m+1)
#dp (bottom-up)
d[0]=0
for i in range(n):
for j in range(array[i],m+1):
if d[j-array[i]]!=10001:#if exists
d[j]=min(d[j],d[j-array[i]]+1)
if d[m]==10001:print(-1)
else: print(d[m])
Q. ๊ธ๊ด
Q. nxm ํฌ๊ธฐ์ ๊ธ๊ด์ด ์๋ค. ๊ธ๊ด์ 1 x 1 ํฌ๊ธฐ์ ์นธ์ผ๋ก ๋๋์ด์ ธ ์์ผ๋ฉฐ, ๊ฐ ์นธ์ ํน์ ํ ํฌ๊ธฐ์ ๊ธ์ด ๋ค์ด ์๋ค. ์ฑ๊ตด์๋ ์ฒซ๋ฒ์งธ ์ด๋ถํฐ ์ถ๋ฐํ์ฌ ๊ธ์ ์บ๊ธฐ ์์ํ๋ค. ๋งจ ์ฒ์์๋ ์ฒซ ๋ฒ์งธ ์ด์ ์ด๋ ํ์์๋ ์ถ๋ฐํ ์ ์๋ค. ์ดํ์ m-1๋ฒ์ ๊ฑธ์ณ์ ๋งค๋ฒ ์ค๋ฅธ์ชฝ ์, ์ค๋ฅธ์ชฝ, ์ค๋ฅธ์ชฝ ์๋ 3๊ฐ์ง ์ค ํ๋์ ์์น๋ก ์ด๋ํด์ผ ํ๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ์ฑ๊ตด์๊ฐ ์ป์ ์ ์๋ ๊ธ์ ์ต๋ ํฌ๊ธฐ๋ฅผ ์ถ๋ ฅํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ์.
for _ in range(int(input())):
n,m=map(int,input().split())
l=list(map(int,input().split()))
golds=[]
digs=[[0]*m for _ in range(n)]
length=len(l)
j,ans=0,0
#2-dimensional array (golds)
for i in range(0,length+1,m):
if j==n:break
golds.append(l[i:i+m])
j+=1
#assign first col
for i in range(0,n):
digs[i][0] = golds[i][0]
#dp-table - digs (bottom-up)
for col in range(1,m):
for row in range(0,n):
if row==0:
digs[row][col]=max(digs[row][col-1],digs[row+1][col-1])+golds[row][col]
elif row==(n-1):
digs[row][col]=max(digs[row][col-1],digs[row-1][col-1])+golds[row][col]
else:
digs[row][col]=max(digs[row][col-1],digs[row+1][col-1],digs[row-1][col-1])+golds[row][col]
#find the maximum value of the last column of 'digs'
for i in range(0,n):
ans=max(ans,digs[i][-1])
print(ans)
๐ฅ 2์ฐจ์ ๋ฐฐ์ด์ ๋ค๋ฃจ์ด์ผ ํ๋ ๋ฌธ์ ์ด๋ฏ๋ก ์์ ๋ฌธ์ ๋ณด๋ค ์ฝ๊ฐ ๋์ด๋๊ฐ ๋์๋ค. digs๋ผ๋ dp-table์ ๋ง๋ ๋ค. ์ด ๋ golds[i][j] = iํ j์ด์ ์กด์ฌํ๋ ๊ธ์ ์, digs[i][j] = iํ j์ด๊น์ง์ ์ต์ ์ ํด๋ ์ป์ ์ ์๋ ๊ธ์ ์ต๋๊ฐ์ผ๋ก ์ค์ .
โ 1์ด๊ณผ ๋ง์ง๋ง ์ด์ด ์๋ ๋ชจ๋ ์ด์ ์ต์ ์ ๊ธ์ ์ ๊ตฌํ๊ธฐ
digs[i][j] = golds[i][j] + max(golds[i-1][j-1], golds[i][j-1], golds[i+1][j-1])
โก 1์ด์ ์ต์ ์ ๊ธ์ ์ ๊ตฌํ๊ธฐ ์ ํ์
digs[i][j] = golds[i][j] + max(golds[i][j-1], golds[i+1][j-1])
โข ๋ง์ง๋ง ์ด์ ์ต์ ์ ๊ธ์ ์ ๊ตฌํ๊ธฐ ์ ํ์
digs[i][j] = golds[i][j] + max(golds[i-1][j-1], golds[i][j-1])
๐ฅ ๋ณ๋์ dp-table์ ๋ง๋ค์ง ์๊ณ ํ dp table update
for tc in range(int(input())):
#mine info
n,m=map(int,input().split())
array=list(map(int,input().split()))
#dp-table initialization
dp=[]
index=0
for i in range(n):
dp.append(array[index:index+m])
index+=m
#dp(bottom-up)
for j in range(1,m):
for i in range(n):
#from upper-left
if i==0: left_up=0
else: left_up=dp[i-1][j-1]
#from lower-left
if i==n-1:left_down=0
else: left_down=dp[i+1][j-1]
#from left
left=dp[i][j-1]
#dp-table update
dp[i][j]=dp[i][j]+max(left_up, left_down, left)
res=0
for i in range(n):
res=max(res,dp[i][m-1])
print(res)
'Computer Science > Algorithms' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐ธCoordinate Compression๐ธ (0) | 2023.01.24 |
---|---|
๐ผ Regular Expression (0) | 2023.01.11 |
bitmasking (0) | 2022.12.20 |
๐ Binary Search ๐ (2) | 2022.12.06 |
understanding pesudo-code of QuickSort (0) | 2022.12.05 |
๋๊ธ