๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ (DP)

๐Ÿ” ๊ฐœ์š”

  • ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆ„์–ด, ์ž‘์€ ๋ฌธ์ œ์˜ ํ•ด๋ฅผ ์ €์žฅํ•˜๊ณ  ์žฌํ™œ์šฉํ•˜์—ฌ ํฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ
  • ์กฐ๊ฑด
    1. ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ โ†’ ๊ฐ™์€ ๊ณ„์‚ฐ์ด ๋ฐ˜๋ณต๋จ (ex. ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด)
    2. ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ โ†’ ํฐ ๋ฌธ์ œ์˜ ์ตœ์ ํ•ด๊ฐ€ ์ž‘์€ ๋ฌธ์ œ์˜ ์ตœ์ ํ•ด๋“ค๋กœ๋ถ€ํ„ฐ ๊ตฌ์„ฑ ๊ฐ€๋Šฅ

๐Ÿค” ํ•ต์‹ฌ ์ ‘๊ทผ ๋ฐฉ๋ฒ•

(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]);
}