[Algorithms] Dynamic Programming
/*
๊ฐ์ ์ ๋ฆฌ
*/
Dynamic Programming(๋์ ๊ณํ๋ฒ) ์ด๋?
์ฒ์์ ์ฃผ์ด์ง ํฐ ๋ฌธ์ ๋ฅผ ์ฌ๋ฌ๊ฐ์ ์์ ๋ฌธ์ ๋ก ๋๋์ด ํธ๋ ๋ฐฉ๋ฒ์ ๋งํฉ๋๋ค. ์ด๋? Divide&Conquer(๋ถํ ์ ๋ณต๊ธฐ๋ฒ)๋ ๊ฐ์๊ฑฐ ์๋๊ฐ? ํ ์๋ ์์ง๋ง, ํฐ ์ฐจ์ด์ ํ๋๊ฐ ์์ต๋๋ค. Dynamic Programming ์ ์ค๋ณต ๊ณ์ฐ์ ํ์ง ์๋๋ค๋ ์ ์ ๋๋ค. Divide&Conquer ์์๋ ํฐ ๋ฌธ์ ๋ฅผ ์ฌ๋ฌ๊ฐ์ ์์ ๋ฌธ์ ๋ก ๋๋ ํ์, ์์ ๋ฌธ์ ๋ฅผ ๊ณ์ฐํ๊ณ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๊ฒฐํฉํด ์ ๋จ๊ณ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ์์ด์์ต๋๋ค. Dynamic Programming ์์๋ ์ด์ ๊ฑฐ์ ์ ์ฌํ์ง๋ง, ๋๋ ์ง ์์ ๋ฌธ์ ๋ค ์ค ์ด๋ฏธ ์์ ๊ณ์ฐํ ์ ์ด ์๋ ์ฐ์ฐ์ด๋ผ๋ฉด ์ด๋ฅผ ์ค๋ณตํด์ ๊ณ์ฐํ์ง ์๊ณ ์ด์ ์ ๊ฒฐ๊ณผ๊ฐ์ ๋ถ๋ฌ์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ฌํ ์ด์ ์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๋ค๋ ํน์ง ๋๋ฌธ์, Divide&Conquer ๋ณด๋ค ์ถ๊ฐ์ ์ธ Space ๊ฐ ํ์ํ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํฉ๋๋ค.
Dynamic Programming ์ ์ ์ฉํ๊ธฐ ์ํ ์กฐ๊ฑด
๋ชจ๋ ๋ฌธ์ ์ ์ด๋ฐ Dynamic Programming ์ ์ ์ฉํ ์ ์์ผ๋ฉด ์ข๊ฒ ์ง๋ง.. ์ ์ฉํ๊ธฐ ์ํ ์กฐ๊ฑด์ด ์์ต๋๋ค.
1. Overlapping Subproblems : ์์์ Subproblem์ ์ฌ๋ฌ๋ฒ ๋ง๋๋ค -> ์ฌ๋ฌ๋ฒ ๋ง๋์ผ ์ฐ์ฐ ๊ฒฐ๊ณผ ์ ์ฅํ ๋ณด๋์ด ์์ผ๋๊น์!
2. Optimal Substructure : ํ์ฌ ๋ง๋ subproblem ์ ๊ทธ ๋ฌธ์ ์ substructure ์ ์ด์ฉํด ํด๊ฒฐํ๋ค. ์ด๋ ๊ทธ ๋ฌธ์ ์ subproblem ๋ํ Optimal ํด์ผ ํ๋ค.
Dynamic Programming ์ ์ ๊ทผ ๋ฐฉ๋ฒ
Dyanmic Programming ์ ํฌ๊ฒ ๋๊ฐ์ง์ ์ ๊ทผ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
1. top-down approach(ํํฅ์ ์ ๊ทผ) : ํฐ ๋ฌธ์ ๋ถํฐ ์ถ๋ฐํด์ ๋์ด์ ์ชผ๊ฐค ์ ์์ ๋๊น์ง ์ชผ๊ฐ๊ณ ํด๊ฒฐ. ๋ณดํต ์ฌ๊ท(Recursion) ์ผ๋ก ๊ตฌํ
2. bottom-up approach(์ํฅ์ ์ ๊ทผ) : ์ฒ์๋ถํฐ ์์ ๋ฌธ์ ๋ก ์์ํ๊ณ , ๋ฌธ์ ์ ํฌ๊ธฐ๋ฅผ ์ ์ ๋๋ ค๊ฐ๋ฉฐ ํด๊ฒฐ. ๋ณดํต ๋ฐ๋ณต๋ฌธ(Loop) ์ผ๋ก ๊ตฌํ
๋ณธ ํฌ์คํ ์์๋ ํํฅ์ ์ ๊ทผ ๋ฐฉ์์ Dynamic Programming ๋ง ๋ค๋ฃฐ ๊ฒ์ ๋๋ค.
Dynamic Programming Version of a Recursive Algorithm(Top-Down Approach)
Dynamic Programming ์ ์์ ์์ ํ๋ฏ์ด ์ค๋ณต ์ฐ์ฐ์ ์์ ๊ณ ์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๋ ๋ฐฉ์์ ์ฑํํจ์ผ๋ก์จ, ๊ณต๊ฐ๊ณผ ์๋๋ฅผ ๊ฑฐ๋ํ ์ ์ด ๋ฉ๋๋ค. Subproblems ๋ค์ ์๋ฃจ์ (์ฐ์ฐ ๊ฒฐ๊ณผ)๋ค์ soln ์ด๋ผ๋ ์ด๋ฆ์ ๋ฐฐ์ด์ ์ ์ฅ๋ฉ๋๋ค. Subproblem Q๋ฅผ ํด๊ฒฐํด์ผ ํ ๋, ์ฌ๊ท๋ฅผ ํธ์ถํ๊ธฐ ์ ๋จผ์ soln ์ ์ ์ฅ๋ ์๋ฃจ์ ์ด ์๋์ง ๋จผ์ ์ฒดํฌํฉ๋๋ค. ๋ง์ฝ ๊ฐ์ด ์ด๋ฏธ ์๋ค๋ฉด ์ด๋ฅผ ์ฌ์ฉํ๊ณ ์ฌ๊ท๋ฅผ ํธ์ถํ์ง ์์ผ๋ฉฐ, ์๋ค๋ฉด ์ฌ๊ท๋ฅผ ํธ์ถํ์ฌ ์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ soln ์ ์ ์ฅํฉ๋๋ค.
Dynamic Programming ์ ์์๋ก ํผ๋ณด๋์น ์๋ฅผ ๊ตฌํ๋ Pseudo-Code ๋ฅผ ๋ณด๊ฒ ์ต๋๋ค. Dynamic Programming ์ ๋๊ฐ์ง ์ ๊ทผ ๋ฐฉ์์ ์ดํดํ๊ธฐ ์ํด์ Bottom-Up Approach ๋ฐฉ์์ Pseudo-Code ๋ ์์ฑํด๋์์ต๋๋ค.
// Top-Down Approach
fipDPwrap_td(n) // n : ๊ตฌํ๋ ค๋ ํผ๋ณด๋์น n๋ฒ์งธ ํญ
Dict soln = create(n); // size๊ฐ n+1 ์ธ Array ์์ฑ
return fibDP_td(soln, n); // Entry Point
fibDP_td(soln, k)
int fib, f1, f2;
if (k < 2)
fib = k;
else
if (member(soln, k-1) == false) // ํผ๋ณด๋์น k-1 ๋ฒ์งธ ํญ์ด ์ ์ฅ๋์ด ์์ง ์๋์..?
f1 = fibDP_td(soln, k-1); // ๊ทธ๋ฌ๋ฉด ์ฌ๊ท ํจ์ ํธ์ถ๋ก ๊ณ์ฐ!
else // ํ k-1 ๋ฒ์งธ ํญ์ด ์ ์ฅ๋์ด ์๋์?
f1 = retrieve(soln, k-1); // ๊ทธ๋ฌ๋ฉด ๊ฐ์ ธ์!
if (member(soln, k-2) == false) // ํผ๋ณด๋์น k-2 ๋ฒ์งธ ํญ์ด ์ ์ฅ๋์ด ์์ง ์๋์..?
f2 = fibDP_td(soln, k-2); // ๊ทธ๋ฌ๋ฉด ์ฌ๊ท ํจ์ ํธ์ถ๋ก ๊ณ์ฐ!
else // ํ k-2 ๋ฒ์งธ ํญ์ด ์ ์ฅ๋์ด ์๋์?
f2 = retrieve(soln, k-2); // ๊ทธ๋ฌ๋ฉด ๊ฐ์ ธ์!
fib = f1 + f2; // ์์์ ๊ณ์ฐ ๋๋ ๊ฐ์ ธ์จ k-1 ๋ฒ์งธ, k-2 ๋ฒ์งธ ํผ๋ณด๋์น ์๋ฅผ ๋ํด์ k ๋ฒ์งธ ํผ๋ณด๋์น ์๋ฅผ ๊ตฌํ๊ธฐ
store(soln, k, fib); // ์ด๋ฒ์ ๊ณ์ฐํ k ๋ฒ์งธ ํผ๋ณด๋์น ์๋ฅผ soln ์ ์ ์ฅ. ๋์ค์ ๋ ์จ๋จน์ด์ผ์ง
return fib; // ๊ณ์ฐํ ๊ฐ ๋ฐํ
// Bottom-Up Approach
fipDPwrap_bu(n) // n : ๊ตฌํ๋ ค๋ ํผ๋ณด๋์น n๋ฒ์งธ ํญ
Dict soln = create(n); // size๊ฐ n+1 ์ธ Array ์์ฑ
return fibDP_bu(soln, n); // Entry Point
fibDP_bu(soln, k)
int fib, f1, f2;
if (k < 2)
fib = k;
else
if (member(soln, k-1) == false) // ํผ๋ณด๋์น k-1 ๋ฒ์งธ ํญ์ด ์ ์ฅ๋์ด ์์ง ์๋์..?
f1 = fibDP_bu(soln, k-1); // ๊ทธ๋ฌ๋ฉด ์ฌ๊ท ํจ์ ํธ์ถ๋ก ๊ณ์ฐ!
else // ํ k-1 ๋ฒ์งธ ํญ์ด ์ ์ฅ๋์ด ์๋์?
f1 = retrieve(soln, k-1); // ๊ทธ๋ฌ๋ฉด ๊ฐ์ ธ์!
if (member(soln, k-2) == false) // ํผ๋ณด๋์น k-2 ๋ฒ์งธ ํญ์ด ์ ์ฅ๋์ด ์์ง ์๋์..?
f2 = fibDP_bu(soln, k-2); // ๊ทธ๋ฌ๋ฉด ์ฌ๊ท ํจ์ ํธ์ถ๋ก ๊ณ์ฐ!
else // ํ k-2 ๋ฒ์งธ ํญ์ด ์ ์ฅ๋์ด ์๋์?
f2 = retrieve(soln, k-2); // ๊ทธ๋ฌ๋ฉด ๊ฐ์ ธ์!
Matrix-Chain Multiplication
Dynamic Programming ์ ํ์ฉํ ์ ์๋ ๋ฌธ์ ๊ฐ ์์ ํผ๋ณด๋์น ์์ด์ ๊ตฌํ๋ ๋ฌธ์ ๋ง๊ณ ๋ ๋ ์์ต๋๋ค. ๋ฐ๋ก ์ฒด์ธ์ฒ๋ผ ์ด์ด์ง ํ๋ ฌ์ ๊ณฑํ๋ ์ฐ์ฐ์์, ์ต์ ์ฐ์ฐ์ผ๋ก ํด๊ฒฐํ ์ ์๋ ์์๋ฅผ ์ฐพ๋ ๋ฌธ์ ์ ๋๋ค. ์ด๋ฅผ Matrix-Chain Multiplication ์ด๋ผ๊ณ ํฉ๋๋ค.
์ฒด์ธ์ฒ๋ผ ์ด์ด์ง n ๊ฐ์ ํ๋ ฌ $<A_{1}, A_{2}, ..., A_{n}>$ ์ด ์ฃผ์ด์ก์ ๋, ์ฐ๋ฆฌ๋ $A_{1} * A_{2} * A_{3} * ... A_{n}$ ์ ๊ฒฐ๊ณผ๋ฅผ ์ฐ์ฐํด์ผ ํฉ๋๋ค. ๊ฒฐ๊ณผ๋ฅผ ๊ตฌํ ๋ ํ์ํ ์ฐ์ฐ๋์ ์๋์ ๊ทธ๋ฆผ์ฒ๋ผ ๊ตฌํ ์ ์์ต๋๋ค.
๋ง์ฝ $A_{1}$ = 30 x 1, $A_{2}$ = 1 x 40, $A_{3}$ = 40 x 10, $A_{4}$ = 10 x 25 ์ ๊ฐ์ด ํ๋ ฌ์ด ๋ค์ด์๋ค๋ฉด ์๋์ ๊ฐ์ ๊ฒฝ์ฐ์ ์๊ฐ ๋์ต๋๋ค.
1. $((A_{1}*A_{2})*A_{3})*A_{4}$ : 30 x 1 x 40 + 30 x 40 x 10 + 30 x 10 x 25 = 20,700 ๋ฒ์ ์ฐ์ฐ์ด ํ์
2. $A_{1}*(A_{2}*(A_{3}*A_{4}))$ : 40 x 10 x 25 + 1 x 40 x 25 + 30 x 1 x 25 = 11,750 ๋ฒ์ ์ฐ์ฐ์ด ํ์
3. $(A_{1}*A_{2})*(A_{3}*A_{4})$ : 30 x 1 x 40 + 40 x 10 x 25 + 30 x 40 x 25 = 41,200 ๋ฒ์ ์ฐ์ฐ์ด ํ์
4. $A_{1}*((A_{2}*A_{3})*A_{4})$ : 1 x 40 x 10 + 1 x 10 x 25 + 30 x 1 x 25 = 1,400 ๋ฒ์ ์ฐ์ฐ์ด ํ์
์์ ๊ฐ์ด ๊ดํธ๋ฅผ ์ด๋์ ์์ฐ๋์ ๋ฐ๋ผ์ ํ์ํ ์ฐ์ฐ๋์ด ๋ฌ๋ผ์ง๋๋ค. ์ ๊ฒฝ์ฐ์ ์ ์ค 4๋ฒ์งธ์ ๊ฐ์ด ์ต์ ์ฐ์ฐ์ผ๋ก ํ๋ ฌ์ ๊ณฑ์ ์ ํ ์ ์๋, Optimal Parenthesization ์ ์ฐพ์์ผ ํฉ๋๋ค.
Step 1. The structure of an Optimal Parenthesization
Ai ๋ถํฐ Aj ๊น์ง์ ํ๋ ฌ์ index k ๊ธฐ์ค์ผ๋ก ๋๊ฐ์ ๋ถ๋ถ์ผ๋ก ๋๋์ด์ค๋๋ค. ๊ทธ๋ผ $A_{i}$~$A_{k}$ ์ $A_{k+1}$~$A_{j}$ ์ ๊ฐ์ด ๋๋๊ฒ ๋ฉ๋๋ค. ์ด๋ k ๋ i ≤ k < j ์ ๊ด๊ณ์ ๋๋ค. ๊ทธ๋ผ Cost(๊ณฑ์ ์ฐ์ฐ ์)๋ฅผ ์๋์ ๊ฐ์ด ๊ณ์ฐํ ์ ์๊ฒ ๋ฉ๋๋ค.
$ Cost\,=\,(cost\,of\,computing\,A_{i..k})\,+\,(cost\,of\,computing\,A_{k+1..j})\,+\,(cost\,of\,multiplying\,them)$
$ A_{i}$~$A_{k} $๊น์ง ๊ณฑ์ ์ฐ์ฐ ํ ๋์จ ๊ฒฐ๊ณผ ํ๋ ฌ์ X, $ A_{k+1}$~$A_{j}$ ๊น์ง ๊ณฑ์ ์ฐ์ฐ ํ ๋์จ ๊ฒฐ๊ณผ ํ๋ ฌ์ Y ๋ผ๊ณ ํ์ ๋, ์ต์ข ๊ฒฐ๊ณผ ํ๋ ฌ์ ๊ตฌํ๊ธฐ ์ํด์ X ์ Y ๋ฅผ ๊ณฑ์ ์ฐ์ฐํด์ผ ํฉ๋๋ค. ์ด๋ ๋๋ ๋น์ฉ์ด ๋ง์ง๋ง์ ๋ํด์ฃผ๋ ํญ์ ๋๋ค.
์ด๋, $ A_{i}$~$A_{k}$ ์ $ A_{k+1}$~$A_{j} $ ๋ ์ด๋ ํ k ๊ฐ์ ๋ํด์ optimal ํด์ผ ํฉ๋๋ค. ์ต์ ๋น์ฉ์ด ๋ฐ์ํ๋ k ๊ฐ์ ์ฐพ๊ธฐ ์ํด์๋, ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ณ์ฐํด๋ณด์์ผ ํฉ๋๋ค.
Step 2. A Recursive Solution
์ฐ๋ฆฌ๋ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ 2 ๊ฐ์ Dynamic Table ์ด ํ์ํฉ๋๋ค. m table ๊ณผ s ํ ์ด๋ธ์ ๋๋ค.
m table
Ai..Aj ๋ฅผ ๊ณ์ฐํ ๋ ํ์ํ Scalar Multiplications ์ ์ต์๊ฐ์ ์ ์ฅํ๋ ํ
์ด๋ธ์
๋๋ค. ๋ง์ฝ i์ j๊ฐ ๋๋ค 0 ์ผ ๋, m[i, j] ๋ 0์
๋๋ค. A0 ~ A0 ๊น์ง ๊ณฑํ๋ ์ฐ์ฐ์ ์ํ๋์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค.
$ m[i,j] = min\,{m[i,\,k]\,+\,m[k+1,\,j]\,+\,p_{i-1}p_{k}p_{j}}\,\,(if\,\,i<j) $
$ m[i,\,k]\,=\,p_{i-1}\,*\,p_{k} $
$ m[k+1,\,j]\,=\,p_{k}\,*\,p_{j} $
$ p_{i-1}p_{k}p_{j} $ : i~k ์ k+1~j ์ ๊ฒฐ๊ณผ๋ก ๋์จ 2๊ฐ์ ํ๋ ฌ์ ๊ณฑํ๋ ๋ฐ์ ํ์ํ ์ฐ์ฐ ์
s table
m table ํน์ ํ k ๋ฅผ ๊ธฐ์ค์ผ๋ก ๋๋์ด์ ์ฐ์ฐํ์ ๋, ํ์ํ ์ฐ์ฐ ์๋ฅผ ์ ์ฅํ๋ table ์ด๋ผ๊ณ ํ๋ค๋ฉด, s table ์ ๊ทธ k ์ ์์น๋ฅผ ์ ์ฅํ๋ table ์
๋๋ค. ์ฌ์ค s table ์ ๋ฐ์์ ํ step 4 ์์ ํ์ํฉ๋๋ค. ์ฆ, step 4๋ฅผ ์ํํ์ง ์์ ๊ฒ์ด๋ผ๋ฉด s table ์ ํ์ํ์ง ์์ต๋๋ค.
์ ๋ ฅ๊ฐ์ผ๋ก ๋ค์ด์ค๋ ํ๋ ฌ์ ์๋ฅผ n ๊ฐ๋ผ๊ณ ํ ๋, ๋ ๊ฐ์ table ๋ชจ๋ n x n ํํ์ 2์ฐจ์ ๋ฐฐ์ด์ ๋๋ค.
Step 3. Computing the Optimal Costs
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก, Optimal Costs ๋ฅผ ๊ตฌํด๋ณด๊ฒ ์ต๋๋ค. ๋จผ์ Pseudo-Code ์ ๋๋ค.
MATRIX-CHAIN-ORDER(p)
n <- length[p] - 1 // ํ๋ ฌ์ ์ฐจ์ ์
๋ ฅ๊ฐ์ธ p ๋, ํ๋ ฌ์ ๊ฐ์ + 1 ๊ฐ์
๋๋ค.
for i <- to n
m[i, i] <- 0 // m table ์ ๋๊ฐ์ ์ 0์ผ๋ก ์ด๊ธฐํ
for l <- 2 to n // l : 2~n // Chain Length
for i <- 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, j]
m[i, j] <- q // Optimal Costs ์
๋ฐ์ดํธ
s[i, j] <- k // Optimal Costs ๊ฐ ๋ฐ์ํ k ๊ฐ ์ ์ฅ/์
๋ฐ์ดํธ
return m and s
$ A_{1} = 30\ast1, A_{2}=1\ast40, A_{3}=40\ast10, A_{4}=10\ast25$
์์๋ก ์ฌ์ฉํ ํ๋ ฌ์ด ์์ ๊ฐ์ ๋, ์ ์ฝ๋์ ์ํ ๋ฐฉ์์ ๊ทธ๋ฆผ์ผ๋ก ์์๋ณด๊ฒ ์ต๋๋ค.
m table ์์ j<i ์ธ ์์ญ์ ์ฌ์ฉํ์ง ์๋ ์ด์ ๋, j<i ๋ผ๋ฉด $A_{i} ~ A_{j}$์ ํ๋ ฌ ๊ณฑ์ด ์ ์๋์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ฐ์ฅ ์ ํ๋ ฌ์ด i ๋ฒ์งธ, ๊ฐ์ฅ ๋ง์ง๋ง ํ๋ ฌ์ด j ๋ฒ์งธ์ฌ์ผ ํ๋ฏ๋ก, j๊ฐ i ๋ณด๋ค ์์ ์ ์์ต๋๋ค.
๋น์ทํ ์ด์ ๋ก s table์์ j <= i ์ธ ์์ญ์ ์ฌ์ฉํ์ง ์์ต๋๋ค. j=i ์ผ ๋๋ ์ฌ์ฉํ์ง ์๋ ์ด์ ๋, s table ์ $A_{i} ~ A_{j} $์ฌ์ด์ ๋๋๋ ์ง์ k ๊ฐ์ ์ ์ฅํ๋ ํํ์ธ๋ฐ i์ j ๊ฐ ๊ฐ๋ค๋ฉด ๋๋๋ ์ง์ k ๋ ์ ์๋์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค.
์์์ ๊ณ์ฐํ ๋ฐฉ์์ผ๋ก, ์ฐ๋ฆฌ๋ Optimal Costs ๋ฅผ ๊ตฌํ ์ ์์ต๋๋ค.
Step 4. Constructing an Optimal Solution
์์์ ๊ตฌํ ์ต์ ๋น์ฉ์ด ๋๋ ์์(๊ณผ์ )์ ๋ง๋๋ ๋จ๊ณ์ ๋๋ค. ์ฐ๋ฆฌ๋ ์์ 1,400 ๋ฒ์ ๊ณฑ์ ์ฐ์ฐ์ด ์ต์ ๋น์ฉ์ด๋ผ๋ ๊ฒ์ ์์๋์ต๋๋ค. ์ด ๋จ๊ณ์์๋ ์ด ๊ณฑ์ ์ฐ์ฐ์ด ๋ฐ์ํ๋ Optimal Parenthesization(Solution) ์ ๋ง๋๋ ๋จ๊ณ๋ก, ์ด ๋จ๊ณ์์ ์ฐพ์๋ด๋ ๊ฒฐ๊ณผ๋ A1*((A2*A3)*A4) ์ ๋๋ค. ์๋๋ ์ด ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๋ Pseudo-Code ์ ๋๋ค.
PRINT_OPTIMAL_PARENS(s, i, j)
if i = j // Base Case
then print "A"i // Ai ๋ฅผ ์ถ๋ ฅ.
else
print "(" // ์ฌ๋ ๊ดํธ ์ถ๋ ฅ
PRINT_OPTIMAL_PARENS(s, i, s[i, j]) // s[i, j] ๋ k ๊ฐ์ ์๋ฏธ. i~k
PRINT_OPTIMAL_PARENS(s, s[i, j] + 1, j) // k+1 ~ j
print ")" // ๋ซ๋ ๊ดํธ ์ถ๋ ฅ
์ ์๊ณ ๋ฆฌ์ฆ์ ์ํ ๋ฐฉ์์ ์๋์ ๊ทธ๋ฆผ์ฒ๋ผ ํธ๋ฆฌ๋ก ํํํ ์ ์์ต๋๋ค.
์ํ ์๊ฐ์ ๋ถ์ํด๋ณด๋ฉด, ํ๋์ ๋ ธ๋๋ ์์ ์๊ฐ(O(1))์ ์ฒ๋ฆฌ ๊ฐ๋ฅํฉ๋๋ค. Proper Binary Tree ๋ผ๊ณ ๊ฐ์ ํ ๋, Leaf Node ๊ฐ n ๊ฐ๋ผ๊ณ ํ ๋, Internal Node ๋ n-1 ๊ฐ์ ๋๋ค. ์ด๋์ ์ด ์ํ ์๊ฐ์ O(2n+1) time == O(n) time ์ ๋๋ค. ์ฆ Linear time ์ ์ํ ๊ฐ๋ฅํฉ๋๋ค. ๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ๋ณด๋ฉด, ์ ์ฝ๋๊ฐ ์ํ๋๊ธฐ ์ํด์๋ s table ์ด ํ์ํฉ๋๋ค. ์ฆ O(n^2) space ๊ฐ ํ์ํฉ๋๋ค.
Dynamic Programming ๋ฅผ ํ์ฉํด๋ณผ ์ ์๋ ๋ฌธ์ ์
๋๋ค. Top-Down Approach, Bottom-Up Approach ๋๊ฐ์ง ๋ฐฉ์์ผ๋ก ๋ชจ๋ ํ์ด๋ณด์๋๊ฑธ ์ถ์ฒ๋๋ฆฝ๋๋ค.
- LeetCode
- Baekjoon
์ ๊ฐ LeetCode ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
// Top-Down Approach
class Solution
{
private:
int F[33];
public:
int fibon(int n)
{
int ans, f1, f2;
if (n < 2)
return n;
else
{
if (F[n - 1] == -1)
f1 = fibon(n - 1);
else
f1 = F[n - 1];
if (F[n - 2] == -1)
f2 = fibon(n - 2);
else
f2 = F[n - 2];
ans = f1 + f2;
F[n] = ans;
return ans;
}
}
int fib(int n)
{
memset(F, -1, 33 * sizeof(int));
int ans = fibon(n);
return ans;
}
};
// Bottom-Up Approach
class Solution {
public:
int fib(int n) {
if (n==0) return 0;
int *F = new int[n+1]; // Array
F[0] = 0; F[1] = 1; // Initialization
for (int i=2; i<=n; i++)
F[i] = F[i-1] + F[i-2];
return F[n];
}
};
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
[Algorithms] String(Pattern) Matching
[Algorithms] String(Pattern) Matching
2023.06.01 -
[C++] ๋ฐฑ์ค BOJ 21939 ๋ฌธ์ ์ถ์ฒ ์์คํ Version 1
[C++] ๋ฐฑ์ค BOJ 21939 ๋ฌธ์ ์ถ์ฒ ์์คํ Version 1
2021.11.18 -
[C++] ๊ฑฐ๋ฆฌ๋๊ธฐ ํ์ธํ๊ธฐ(2021 ์นด์นด์ค ์ฑ์ฉ์ฐ๊ณํ ์ธํด์ญ ์ฝ๋ฉํ ์คํธ)
[C++] ๊ฑฐ๋ฆฌ๋๊ธฐ ํ์ธํ๊ธฐ(2021 ์นด์นด์ค ์ฑ์ฉ์ฐ๊ณํ ์ธํด์ญ ์ฝ๋ฉํ ์คํธ)
2021.11.03 -
[Python] ์ซ์ ๋ฌธ์์ด๊ณผ ์๋จ์ด(2021 ์นด์นด์ค ์ฑ์ฉ์ฐ๊ณํ ์ธํด์ญ ์ฝ๋ฉํ ์คํธ)
[Python] ์ซ์ ๋ฌธ์์ด๊ณผ ์๋จ์ด(2021 ์นด์นด์ค ์ฑ์ฉ์ฐ๊ณํ ์ธํด์ญ ์ฝ๋ฉํ ์คํธ)
2021.11.03