๐ฆ 11. Recursion & Dynamic programming
11. Recursion & Dynamic programming
์ ๊ทผ๋ฒ
์ฌ๊ท์ ํด๋ฒ์, ๋ถ๋ถ๋ฌธ์ ์ ๋ํ ํด๋ฒ์ ํตํด ์์ฑ๋๋ค.
์ํฅ์ ์ ๊ทผ๋ฒ (Bottom-up)
์ํฅ์ ์ ๊ทผ๋ฒ์ ๊ฐ์ฅ ์ง๊ด์ ์ธ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
์ด ์ ๊ทผ๋ฒ์ ๊ฐ๋จํ ๊ฒฝ์ฐ๋ค์ ๋ํ ํ์ด๋ฒ์ ๋ฐ๊ฒฌํ๋ ๊ฒ์ผ๋ก๋ถํฐ ์์ํด
์ด์ ์ ํ์๋ ์ฌ๋ก๋ฅผ ํ์ฅํ์ฌ ๋ค์ ํ์ด๋ฅผ ์ฐพ๋๋ค.
ํํฅ์ ์ ๊ทผ๋ฒ (Top-down)
์ด๋ป๊ฒ ํ๋ฉด N์ ๋ํ ๋ฌธ์ ๋ฅผ ๋ถ๋ถ ๋ฌธ์ ๋ก ๋๋ ์ ์๋์ง ์๊ฐํด๋ด์ผ ํ๋ค.
๋๋ ๋ถ๋ถ๋ฌธ์ ์ ๊ฒฝ์ฐ ์๋ก ๊ฒน์น์ง ์๋๋ก ์ฃผ์ํ๋ค.
๋ฐ๋ฐ ์ ๊ทผ๋ฒ
๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ผ๋ก ๋๋๋ ๋ฐฉ๋ฒ์ด๋ค.
์ด์ง ํ์๊ณผ ๋ณํฉ ์ ๋ ฌ์ ์ด๋ฐ ์ ๊ทผ๋ฒ์ ์ด์ฉํ๋ค.
์ฌ๊ท์ ํด๋ฒ vs. ์ํ์ ํด๋ฒ
์ฌ๊ท์ ์๊ณ ๋ฆฌ์ฆ์ ๊ณต๊ฐ ํจ์จ์ฑ์ด ๋๋น ์ง ์ ์๋ค.
์ฌ๊ท ํธ์ถ์ด ํ ๋ฒ ๋ฐ์ํ ๋๋ง๋ค ์คํ์ ์๋ก์ด ์ธต์ด ์ถ๊ฐ๋๊ณ
์ฌ๊ท์ ๊น์ด๊ฐ n ์ผ๋ O(n) ๋งํผ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค.
๋ฐ๋ผ์ ์ฌ๊ท์ ์๊ณ ๋ฆฌ์ฆ์ ์ํ์ ์ผ๋ก ๊ตฌํํ๋ ๊ฒ์ด ๋ ๋์ ์๋ ์๋ค.
๋ชจ๋ ์ฌ๊ท์ ์๊ณ ๋ฆฌ์ฆ์ ์ํ์ ์ผ๋ก ๊ตฌํ๋ ์ ์์ง๋ง, ๋๋ก๋ ๋ ๋ณต์กํ๋ค.
๋์ ๊ณํ๋ฒ & ๋ฉ๋ชจ์ด์ ์ด์
๋์ ํ๋ก๊ทธ๋๋ฐ์ ๊ฑฐ์ ๋๋ถ๋ถ ์ฌ๊ท์ ์๊ณ ๋ฆฌ์ฆ๊ณผ ๋ฐ๋ณต์ ์ผ๋ก ํธ์ถ๋๋ ๋ถ๋ถ ๋ฌธ์ ๋ฅผ ์ฐพ์๋ด๋ ๊ฒ์ด ๊ด๊ฑด์ด๋ค.
์ด๋ฅผ ์ฐพ์ ๋ค์ ๋์ค์ ์ํด ํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ์บ์์ ์ ์ฅํด๋๋ฉด ๋๋ค.
๋์ ํ๋ก๊ทธ๋๋ฐ์ ์ค๋ช ํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ์์๋ n๋ฒ์งธ ํผ๋ณด๋์น ์๋ฅผ ์ฐพ๋ ๊ฒ์ด๋ค.
ํผ๋ณด๋์น ์์ด
- ์ฌ๊ท
1
2
3
4
5
int fibonacci(int i) {
if (i == 0) return 0;
if (i == 1) return 1;
return fibonacci(i - 1) + fibonacci(i - 2);
}
๊ฐ ์ฌ๊ทํธ์ถ์ ์์๋๋ ์๊ฐ์ O(1) ์ด๊ณ ํธ๋ฆฌ์ ์๋ ๋ ธ๋์ ๊ฐ์๋ ๋๋ต O(2^n) ๊ฐ์ด๋ค.
๋ฐ๋ผ์ ์ํ ์๊ฐ์ ์ฝ O(2^n) ์ ๋๊ฐ ๋๋ค.
- ํํฅ์ ๋์ ํ๋ก๊ทธ๋๋ฐ(๋ฉ๋ชจ์ด์ ์ด์ )
์ฌ๊ท ํธ๋ฆฌ๋ฅผ ๊ทธ๋ ค๋ณด๋ฉด ๋ง์ ๋ ธ๋๋ค์ด ์ค๋ณต๋์ด ํธ์ถ๋๋ค.
๋งค๋ฒ fib(i) ๋ฅผ ๊ณ์ฐํ ๋๋ง๋ค ์ด ๊ฒฐ๊ณผ๋ฅผ ์บ์ํ๊ณ ์ ์ฅ๋ ๊ฐ์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ฉ๋ชจ์ด์ ์ด์ ์ด๋ค.
1
2
3
4
5
6
7
8
9
10
11
int fibonacci(int n) {
return fibonacci(n, new int[n + 1]);
}
int fibonacci(int i, int[] memo) {
if (i == 0 || i == 1) return i;
if (memo[i] == 0) {
memo[i] = fibonacci(i - 1, memo) + fibonacci(i - 2, memo);
}
return memo[i];
}
- ์ํฅ์ ๋์ ํ๋ก๊ทธ๋๋ฐ
๊ตฌํ์ ์ํฅ์์ผ๋ก ํ ์๋ ์๋ค.
์ฌ๊ท์ ์ธ ๋ฉ๋ชจ์ด์ ์ด์ ์ผ๋ก ์ ๊ทผํ๋, ๊ทธ๊ฑธ ๋ค์ง๋๋ค๊ณ ์๊ฐํด๋ณด์.
1
2
3
4
5
6
7
8
9
10
11
int fibonacci(int n){
if (n == 0) return 0;
else if (n == 1) return 1;
int[] memo = new int[n];
memo[0] = 0;
memo[1] = 1;
for (int i = 2; i < n; i++) {
memo[i] = memo[i - 1] + memo[i - 2];
}
return memo[n - 1] + memo[n - 2];
}
memo[i] ๋ memo[i+1] ๊ณผ memo[i + 2] ๋ฅผ ๊ณ์ฐํ ๋๋ง ์ฌ์ฉ๋๊ณ ๊ทธ ๋ค์๋ ์ฌ์ฉ๋์ง ์๋๋ค.
๋ฐ๋ผ์ ๋ณ์ ๋ช ๊ฐ๋ฅผ ์ฌ์ฉํด์ ํ ์๋ ์๋ค.