๐Ÿ“š Dynamic Programming(DP)


๐Ÿ“š Dynamic Programming


๐Ÿ“š Dynamic Programming์ด๋ž€?

  • ๋ณต์žกํ•œ ๋ฌธ์ œ๋ฅผ ํ’€ ๋•Œ, ์ž‘์€ ๋ฌธ์ œ๋ฅผ ํ’€์–ด๊ฐ€๋ฉฐ ์ „์ฒด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•
  • ์ด ๋ฐฉ์‹์œผ๋กœ ์ค‘๋ณต ๊ณ„์‚ฐ์„ ํ”ผํ•˜๊ณ  ๋ฌธ์ œ๋ฅผ ๋” ํšจ์œจ์ ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.
  • ์ฃผ๋กœ ์ตœ์ ํ™” ๋ฌธ์ œ์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.

๐Ÿ’ก ํ•ต์‹ฌ ์•„์ด๋””์–ด

  • ๋ถ„ํ•  ์ •๋ณต๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ, ์ค‘๋ณต๋œ ๋ถ€๋ถ„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๋•Œ์˜ ํšจ์œจ์„ฑ์— ์ดˆ์ ์ด ๋จ
  • ๋ฌธ์ œ๋ฅผ ๋” ์ž‘์€ ํ•˜์œ„ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆ„๊ณ , ๊ฐ ํ•˜์œ„ ๋ฌธ์ œ๋ฅผ ํ•œ๋ฒˆ๋งŒ ํ’€์–ด ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•œ ํ›„ ์žฌ์‚ฌ์šฉํ•œ๋‹ค.

๐Ÿ’ก DP์˜ ๋‘๊ฐ€์ง€ ์ค‘์š”ํ•œ ์š”์†Œ

  1. ์ค‘๋ณต๋œ ๋ถ€๋ถ„ ๋ฌธ์ œ
    • ๋ฌธ์ œ๋ฅผ ์—ฌ๋Ÿฌ๋ฒˆ ํ’€ ๋•Œ ๋™์ผํ•œ ํ•˜์œ„ ๋ฌธ์ œ๊ฐ€ ๋ฐ˜๋ณตํ•ด์„œ ๋“ฑ์žฅํ•  ๋•Œ๊ฐ€ ์žˆ๋‹ค.
    • ์˜ˆ๋ฅผ ๋“ค์–ด, ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์—์„œ fib(5)๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ fib(4)์™€ fib(3)์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ๊ณ„์‚ฐํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ค‘๋ณต ๊ณ„์‚ฐ์ด ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋Ÿด๋•Œ DP๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•œ๋ฒˆ๋งŒ ๊ณ„์‚ฐํ•˜๊ณ ๊ณ„์‚ฐ์„ ์ €์žฅํ•ด๋‘๊ณ  ์žฌ์‚ฌ์šฉํ•œ๋‹ค
  2. ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ
    • ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•˜์œ„ ๋ฌธ์ œ์˜ ์ตœ์  ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ์ด ์ „์ฒด ๋ฌธ์ œ์˜ ์ตœ์  ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์œผ๋กœ ์ด์–ด์ง„๋‹ค๋Š” ํŠน์„ฑ์ด ์žˆ์–ด์•ผํ•œ๋‹ค.

๐Ÿ”‘ DP์˜ ์ฃผ์š” ์ ‘๊ทผ ๋ฐฉ์‹

  1. **ํƒ‘๋‹ค์šด(Top - Down) ๋ฐฉ์‹(์žฌ๊ท€ + ๋ฉ”๋ชจ์ด์ œ์ด์…˜)**
    • ์žฌ๊ท€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ , ๊ทธ ๊ณผ์ •์—์„œ ๊ณ„์‚ฐํ•œ ๊ฐ’์„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ์„ ํ†ตํ•ด ์ €์žฅํ•˜์—ฌ ์ค‘๋ณต๊ณ„์‚ฐ์„ ํ”ผํ•จ
    • ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ๊ณ„์‚ฐ๋œ ๊ฐ’์„ ๋ฐฐ์—ด์ด๋‚˜ ํ•ด์‰ฌ๋งต์— ์ €์žฅํ•˜๊ณ , ๋™์ผํ•œ ํ•˜์œ„ ๋ฌธ์ œ๊ฐ€ ๋“ฑ์žฅํ•  ๋•Œ ๊ทธ ๊ฐ’์„ ๋ฐ”๋กœ ์ฐธ์กฐ ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

๐Ÿ’ป ํƒ‘๋‹ค์šด ์˜ˆ์‹œ

#include <iostream>
#include <vector>

std::vector<int> memo(100, -1); // -1๋กœ ์ดˆ๊ธฐํ™”, ๋ฒกํ„ฐ์˜ ์ดˆ๊ธฐ ์ดˆ๊ธฐํ™”๊ฐ’์€ -1 ์ด๋‹ค.

int fib(int n) {
    if (n <= 1) return n; // 1์ผ ๋•Œ ๊ฐ’์€ ๋‹น์—ฐํžˆ 1(1๊ฐ€์ง€ ๋ฐฉ๋ฒ•)
    if (memo[n] != -1) return memo[n]; // ์ด๋ฏธ ๊ณ„์‚ฐ๋œ ๊ฐ’์ด ์žˆ์œผ๋ฉด ๋ฐ˜ํ™˜
    memo[n] = fib(n-1) + fib(n-2);    // ๊ณ„์‚ฐ ํ›„ ์ €์žฅ, ์žฌ๊ท€
    return memo[n];
}

int main() {
    std::cout << fib(10) << std::endl; // 55
    return 0;
}
  1. ๋ฐ”ํ… ์—…(Bottom - up) ๋ฐฉ์‹(๋ฐ˜๋ณต๋ฌธ + ํ…Œ์ด๋ธ”)
    • ๋ฌธ์ œ๋ฅผ ์ž‘์€ ํ•˜์œ„ ๋ฌธ์ œ๋ถ€ํ„ฐ ์ฐจ๊ทผ์ฐจ๊ทผ ํ’€์–ด๋‚˜๊ฐ€๋ฉด์„œ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ํ…Œ์ด๋ธ”(๋ฐฐ์—ด, ๋ฆฌ์ŠคํŠธ) ๋“ฑ์— ์ €์žฅํ•ด๊ฐ„๋‹ค.
    • ๋ฐ˜๋ณต๋ฌธ์„ ํ˜ธ์ถœํ•˜๋ฏ€๋กœ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์—†๋‹ค , ํƒ‘๋‹ค์šด ๋ฐฉ์‹์€ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค.
    • ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ํ•˜์œ„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ , ์ตœ์ข…์ ์œผ๋กœ ์›ํ•˜๋Š” ๊ฐ’์„ ํ…Œ์ด๋ธ”์—์„œ ์ฐพ์•„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๐Ÿ’ป ๋ฐ”ํ…€ ์—… ์˜ˆ์‹œ

int fib(int n) {
    std::vector<int> dp(n+1, 0);
    dp[1] = 1;
    for (int i = 2; i <= n; ++i) {
        dp[i] = dp[i-1] + dp[i-2];
    }
    return dp[n];
}

๐Ÿ›  Dynamic Programming์˜ ์‚ฌ์šฉ ์˜ˆ์‹œ

  1. ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด
    • fib(n) = fib(n-1) + fib(n-2)๋กœ ์ •์˜๋˜๋ฉฐ, DP๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ค‘๋ณต ๊ณ„์‚ฐ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ๋ฐฐ๋‚ญ ๋ฌธ์ œ
    • ์ฃผ์–ด์ง„ ๋ฌผ๊ฑด์˜ ๋ฌด๊ฒŒ์™€ ๊ฐ€์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ œํ•œ๋œ ๋ฌด๊ฒŒ ๋‚ด์—์„œ ์ตœ๋Œ€ ๊ฐ€์น˜๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ, ๊ฐ ๋ฌผ๊ฑด์„ ํฌํ•จํ•˜๊ฑฐ๋‚˜ ํฌํ•จํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ์ตœ์  ํ•ด๋ฅผ ์ฐพ๋Š”๋‹ค.
  3. ์ตœ๋‹จ ๊ฒฝ๋กœ ๋ฌธ์ œ
    • ๊ทธ๋ž˜ํ”„์—์„œ ๋‘ ์  ์‚ฌ์ด์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ๋ฌธ์ œ๋กœ, DP๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.
  4. ๋ฌธ์ž์—ด ํŽธ์ง‘ ๊ฑฐ๋ฆฌ
    • ๋‘ ๋ฌธ์ž์—ด์„ ํ•˜๋‚˜๋กœ ๋ฐ”๊พธ๋Š” ์ตœ์†Œ ์ž‘์—… ํšŸ์ˆ˜๋ฅผ ์ฐพ๋Š” ๋ฌธ์ œ๋กœ, ์‚ฝ์ž…, ์‚ญ์ œ, ๊ต์ฒด๋ฅผ ์ตœ์†Œํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ตฌํ•œ๋‹ค.

๐Ÿ“Œ ์ •๋ฆฌ

์žฅ์ 

  • ํšจ์œจ์„ฑ : ์ค‘๋ณต ๊ณ„์‚ฐ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ ํฌ๊ฒŒ ์ค„์–ด๋“ ๋‹ค.
  • ๋ฌธ์ œ ํ•ด๊ฒฐ ๋Šฅ๋ ฅ : ๋ณต์žกํ•œ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ํ•˜์œ„ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆ„์–ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹จ์ 

  • ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ : DP๋Š” ํ•˜์œ„ ๋ฌธ์ œ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•ด์•ผํ•˜๋ฏ€๋กœ ์ถ”๊ฐ€์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ํ•„์š”
  • ๋ฌธ์ œ ๊ตฌ์กฐ๊ฐ€ ์ ํ•ฉํ•ด์•ผ ํ•จ : ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ + ์ค‘๋ณต๋œ ๋ถ€๋ถ„ ๋ฌธ์ œ๋ฅผ ๊ฐ€์ง€๋Š” ๋ฌธ์ œ์—๋งŒ ์œ ํšจ