๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ (DP)
๐ ๊ฐ์
- ํฐ ๋ฌธ์ ๋ฅผ ์์ ๋ฌธ์ ๋ก ๋๋์ด, ์์ ๋ฌธ์ ์ ํด๋ฅผ ์ ์ฅํ๊ณ ์ฌํ์ฉํ์ฌ ํฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐ
- ์กฐ๊ฑด
- ์ค๋ณต๋๋ ๋ถ๋ถ ๋ฌธ์
โ ๊ฐ์ ๊ณ์ฐ์ด ๋ฐ๋ณต๋จ (ex. ํผ๋ณด๋์น ์์ด)
- ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ
โ ํฐ ๋ฌธ์ ์ ์ต์ ํด๊ฐ ์์ ๋ฌธ์ ์ ์ต์ ํด๋ค๋ก๋ถํฐ ๊ตฌ์ฑ ๊ฐ๋ฅ
๐ค ํต์ฌ ์ ๊ทผ ๋ฐฉ๋ฒ
(1) Top-Down (์ฌ๊ท + ๋ฉ๋ชจ์ด์ ์ด์
)
- ํฐ ๋ฌธ์ โ ์์ ๋ฌธ์ ๋ก ๋ถํ
- ์ฌ๊ท ํจ์ ์์์
dp[] ๊ฐ์ด ์ด๋ฏธ ๊ณ์ฐ๋์๋์ง ํ์ธ ํ ์ฌ์ฌ์ฉ
static int[] dp = new int[100];
static int fibo(int n) {
if(n <= 1) {
return n;
}
if(dp[n] != 0) {
return dp[n]; // ์ด๋ฏธ ๊ณ์ฐ๋จ
}
return dp[n] = (fibo(n-1) + fibo(n-2));
}
(2) Bottom-Up (๋ฐ๋ณต๋ฌธ + ํ
์ด๋ธ)
- ์์ ๋ฌธ์ โ ํฐ ๋ฌธ์ ๋ก ํ์ฅ
- ๋ฐ๋ณต๋ฌธ์ผ๋ก
dp[] ๋ฐฐ์ด์ ์ฑ์๊ฐ
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = 1;
for(int i = 2; i <= n; i++) {
dp[i] = dp[i-1] + dp[i-2];
}
โ ๋ํ DP ์ ํ
(A) 1์ฐจ์ DP
- ํผ๋ณด๋์น ์์ด, ๊ณ๋จ ์ค๋ฅด๊ธฐ, 1๋ก ๋ง๋ค๊ธฐ
// ๊ณ๋จ ์ค๋ฅด๊ธฐ: n๋ฒ์งธ ๊ณ๋จ ์ค๋ฅด๋ ๋ฐฉ๋ฒ ์
dp[i] = dp[i-1] + dp[i-2];
(B) 2์ฐจ์ DP (๊ฒฉ์ ๋ฌธ์ )
- ์ต์ ๋น์ฉ ๊ฒฝ๋ก, ์ต๋จ ๊ฒฝ๋ก
// (i, j)๊น์ง ์ต์ ๋น์ฉ
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + cost[i][j];
(C) ๋ฐฐ๋ญ ๋ฌธ์ (Knapsack)
- 0/1 ๋ฐฐ๋ญ: ๋ฌผ๊ฑด์ ๋ฃ๊ฑฐ๋ ์ ๋ฃ๊ฑฐ๋
for(int i = 1; i <= n; i++) {
for(int w = W; w >= weight[i]; w--) {
dp[w] = Math.max(dp[w], dp[w-weight[i]] + value[i]);
}
}
(D) ๊ตฌ๊ฐ DP
- ํฐ๋ฆฐ๋๋กฌ ์ฌ๋ถ, ํ๋ ฌ ๊ณฑ ์ต์ ํ
(E) ๋ฌธ์์ด DP
- LCS(์ต์ฅ ๊ณตํต ๋ถ๋ถ ์์ด)
if(s1[i-1] == s2[j-1]) {
dp[i][j] = dp[i-1][j-1] + 1;
} else {
dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
}