๋ฐ˜์‘ํ˜•

๋™์  ๊ณ„ํš๋ฒ•


๋™์  ๊ณ„ํš๋ฒ•(Dynamic Programming, DP)์€ ๋ณต์žกํ•œ ๋ฌธ์ œ๋ฅผ ๋” ์ž‘์€ ํ•˜์œ„ ๋ฌธ์ œ๋กœ ๋ถ„ํ• ํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๋ฉด์„œ ํฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฌธ์ œ์˜ ์—ฐ์‚ฐ ์‹œ๊ฐ„์„ ํšจ๊ณผ์ ์œผ๋กœ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค. ๋™์  ๊ณ„ํš๋ฒ•์„ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„  ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•ด์•ผ ํ•œ๋‹ค. ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์ด ์•„๋ž˜ ๋‘ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ ์˜ˆ.

 

  • ์ตœ์  ํ•˜์œ„ ๊ตฌ์กฐ Optimal Substructure
    ์ž‘์€ ํ•˜์œ„ ๋ฌธ์ œ์˜ ์ตœ์  ํ•ด๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ์ „์ฒด ๋ฌธ์ œ์˜ ์ตœ์  ํ•ด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
  • ํ•˜์œ„ ๋ฌธ์ œ ์ค‘์ฒฉ Overlapping Subproblem
    ๋™์ผํ•œ ํ•˜์œ„ ๋ฌธ์ œ๊ฐ€ ๋ฐ˜๋ณต์ ์œผ๋กœ ๋ฐœ์ƒํ•œ๋‹ค.

 

๋™์  ๊ณ„ํš๋ฒ•์€ ์ค‘๋ณต ๊ณ„์‚ฐ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ˜น์€ ํƒ€๋ทธ๋ ˆ์ด์…˜ ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ์žฌ๊ท€ ํ˜ธ์ถœ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ๋ฌธ์ œ๋งŒ ๊ณ„์‚ฐํ•˜๊ณ , ํƒ€๋ทธ๋ ˆ์ด์…˜์€ ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ œ์˜ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ํ•ด๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค. ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๊ณ„์‚ฐํ•˜๋ฏ€๋กœ ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ์žฌ๊ท€ ํ˜ธ์ถœ๋กœ ์ธํ•ด ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ์œ„ํ—˜์ด ์žˆ๋‹ค. ํƒ€๋ทธ๋ ˆ์ด์…˜์€ ๋ชจ๋“  ๋ฌธ์ œ์˜ ํ•ด๋ฅผ ๊ณ„์‚ฐํ•˜๋ฏ€๋กœ ๋” ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์žฌ๊ท€ ํ˜ธ์ถœ์˜ ์ œํ•œ ์—†์ด ์•ˆ์ •์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

 

๋™์  ๊ณ„ํš๋ฒ•์€ ํฌ๊ฒŒ ํ•˜ํ–ฅ์‹, ์ƒํ–ฅ์‹ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์œผ๋กœ ๋‚˜๋‰œ๋‹ค.

 

Top-Down (ํ•˜ํ–ฅ์‹)

์ฃผ์–ด์ง„ ๋ฌธ์ œ๋ฅผ ๋” ์ž‘์€ ํ•˜์œ„ ๋ฌธ์ œ๋กœ ๋ถ„ํ•ดํ•˜๋ฉด์„œ ๋ฌธ์ œ ํ•ด๊ฒฐ — ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ™œ์šฉ

 

ํ•˜ํ–ฅ์‹ ๋™์  ๊ณ„ํš๋ฒ•์œผ๋กœ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์„ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜ โ–ผ

function fibonacci(n, memo = [0, 1]) {
  if (memo[n] !== undefined) return memo[n];
  if (n <= 1) return n;

  memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
  return memo[n];
}

 

Bottom-Up (์ƒํ–ฅ์‹)

์ž‘์€ ๋ฌธ์ œ๋ถ€ํ„ฐ ์ˆœ์ฐจ์ ์œผ๋กœ ํ•ด๊ฒฐํ•˜๋ฉด์„œ ์ฃผ์–ด์ง„ ๋ฌธ์ œ ํ•ด๊ฒฐ — ํƒ€๋ทธ๋ ˆ์ด์…˜ ํ™œ์šฉ

 

์ƒํ–ฅ์‹ ๋™์  ๊ณ„ํš๋ฒ•์œผ๋กœ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์„ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜ โ–ผ

function fibonacci(n) {
  const table = [0, 1]; // 0~1๋ฒˆ์งธ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜ ๋ฏธ๋ฆฌ ์„ค์ •

  for (let i = 2; i <= n; i++) {
    table[i] = table[i - 1] + table[i - 2];
  }

  return table[n];
}

 

๋•…๋”ฐ๋จน๊ธฐ ๋ฌธ์ œ


๊ทธ๋ฆฌ๋”” (ํƒ์š•๋ฒ•)

ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค ๋ ˆ๋ฒจ 2์˜ ๋•…๋”ฐ๋จน๊ธฐ ๋ฌธ์ œ๋Š” ๊ฐ ํ–‰(row)์—์„œ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ํฐ ์ˆซ์ž์˜ ํ•ฉ์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค. ๋‹จ, ๊ฐ™์€ ์—ด์„ ์—ฐ์†ํ•ด์„œ ์„ ํƒํ•  ์ˆ˜ ์—†๋Š” ์กฐ๊ฑด์ด ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ฒซ๋ฒˆ์งธ ํ–‰์˜ ๊ฐ€์žฅ ํฐ ์ˆซ์ž์ธ 5๋ฅผ ์„ ํƒํ–ˆ๋‹ค๋ฉด, ๋‹ค์Œ ํ–‰์—์„  5์™€ ๋™์ผํ•œ ์—ด(์ธ๋ฑ์Šค 3)์— ์žˆ๋Š” 8์„ ์„ ํƒํ•  ์ˆ˜ ์—†๋‹ค.

 

๊ทธ๋ฆฌ๋””(Greedy) ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํ˜„์žฌ ์ƒํ™ฉ์—์„œ ์ง€์—ญ์ ์œผ๋กœ ์ตœ์„ ์˜ ์„ ํƒ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ๋•…๋”ฐ๋จน๊ธฐ ๋ฌธ์ œ๋ฅผ ๊ทธ๋ฆฌ๋”” ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผํ•˜๋ฉด ๊ฐ ํ–‰์—์„œ ์ตœ๋Œ€๊ฐ’์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ˆ์‹œ์—์„  ์ตœ์ ์˜ ํ•ด๋ฅผ ๋„์ถœํ•˜์ง€ ๋ชปํ•œ๋‹ค.

 

์œ„ ์˜ˆ์‹œ์—์„  ์ฒซ ๋ฒˆ์งธ ํ–‰์˜ 3, ๋‘ ๋ฒˆ์งธ ํ–‰์˜ 2, ์„ธ ๋ฒˆ์งธ ํ–‰์˜ 4๋ฅผ ์„ ํƒํ•ด์„œ ์ตœ์ ์˜ ํ•ด(๊ฐ€์žฅ ํฐ ์ˆ˜ 9)๋ฅผ ๋„์ถœํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋ฆฌ๋”” ๋ฐฉ์‹์œผ๋กœ ๊ฐ ํ–‰์˜ ์ตœ๋Œ“๊ฐ’์„ ์„ ํƒํ•˜๋ฉด ํ•ฉ์€ 7์ด ๋œ๋‹ค(์•„๋ž˜ ์ฐธ๊ณ ). ๋‘ ๋ฒˆ์งธ ํ–‰์˜ ๊ฐ€์žฅ ํฐ ์ˆ˜ 3์„ ์„ ํƒํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์„ธ ๋ฒˆ์งธ ํ–‰์—์„  ๋™์ผํ•œ ์—ด์— ์žˆ๋Š” 4๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ ๊ฒƒ์ด๋‹ค.

 

๋”ฐ๋ผ์„œ ์ด ๋ฌธ์ œ๋ฅผ ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์˜์กดํ•˜๋ฉด ์ตœ์ ์˜ ํ•ด๋ฅผ ์–ป์„ ์ˆ˜ ์—†๋‹ค. ๊ฐ ๋‹จ๊ณ„์—์„  ์ตœ์ ์˜ ์„ ํƒ์„ ํ–ˆ์ง€๋งŒ, ๊ทธ ์„ ํƒ์ด ํ•ญ์ƒ ์ „์ฒด ๋ฌธ์ œ์˜ ์ตœ์ ํ•ด๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ฆฌ๋”” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•˜๋ ค๋ฉด ์ง€์—ญ์ ์œผ๋กœ ์ตœ์ ์ด๋ฉด์„œ ์ „์—ญ์ ์œผ๋กœ๋„ ์ตœ์ ์ธ ๋ฌธ์ œ์—ฌ์•ผ ํ•œ๋‹ค.

 

๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ๊ฐ ํ–‰์— ์žˆ๋Š” ์—ด(column)์„ ์„ ํƒํ–ˆ์„ ๋•Œ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ“๊ฐ’์„ ๋ชจ๋‘ ๊ณ„์‚ฐํ•ด๋ด์•ผ ํ•œ๋‹ค. ๋‘ ๋ฒˆ์งธ ํ–‰๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ๊ฐ ์—ด์ด ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ“๊ฐ’์„ ์ €์žฅํ•ด ๋‘”๋‹ค๋ฉด, ๋งˆ์ง€๋ง‰ ํ–‰์—์„œ ์ตœ์ ํ•ด๋ฅผ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด ๋‘ ๋ฒˆ์งธ ํ–‰์˜ ์ฒซ ๋ฒˆ์งธ ์—ด 2์™€, ์ฒซ ๋ฒˆ์งธ ํ–‰์˜ ๊ฐ€์žฅ ํฐ ์ˆ˜ 3์„ ๋”ํ•˜๋ฉด, ํ•ด๋‹น ์—ด์„ ์„ ํƒํ–ˆ์„ ๋•Œ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ“๊ฐ’์ด ๋œ๋‹ค. ๋™์ผํ•œ ์—ด์„ ์—ฐ์†ํ•ด์„œ ์„ ํƒํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, ์ด์ „ ํ–‰์˜ ๋™์ผํ•œ ์—ด์€ ๊ณ„์‚ฐ์—์„œ ์ œ์™ธํ•œ๋‹ค. ์ด๋Ÿฐ ์‹์œผ๋กœ ๋‘ ๋ฒˆ์งธ ํ–‰์˜ ๋ชจ๋“  ์—ด์— ๋Œ€ํ•œ ์ตœ๋Œ“๊ฐ’์„ ๊ณ„์‚ฐํ•˜๊ณ  ์ €์žฅํ•œ๋‹ค.

 

 

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

 

ํƒ€๋ทธ๋ ˆ์ด์…˜์„ ์‚ฌ์šฉํ•œ ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ โ–ผ

function solution(land) {
  const row = land.length;
  const column = land[0].length;

  const dp = Array.from({ length: row }, () => Array(column).fill(0)); // 2์ฐจ์› ๋ฐฐ์—ด ์ดˆ๊ธฐํ™”
  dp[0] = land[0].slice(); // ์›๋ณธ(land) ๋ฐฐ์—ด์˜ ์ฒซ๋ฒˆ์งธ ํ–‰์„ ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ์ง€์ •

  for (let i = 1; i < row; i++) {
    for (let j = 0; j < column; j++) {
      const prevRow = dp[i - 1].filter((_, index) => index !== j); // ๋™์ผํ•œ ์—ด์€ ์ œ์™ธ
      const prevRowMax = Math.max(...prevRow); // ํ˜„์žฌ ์—ด์„ ์ œ์™ธํ•œ ์ด์ „ ํ–‰์˜ ์ตœ๋Œ€๊ฐ’ ๊ณ„์‚ฐ
      dp[i][j] = prevRowMax + land[i][j]; // ํ˜„์žฌ ์—ด์„ ์„ ํƒํ–ˆ์„ ๋•Œ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ์ ์ˆ˜ ์ €์žฅ
    }
  }

  return Math.max(...dp.at(-1)); // ๋งˆ์ง€๋ง‰ ํ–‰์˜ ์ตœ๋Œ€๊ฐ’ ๋ฐ˜ํ™˜
}

 

์ด๋ ‡๊ฒŒ ๊ฐ ๋‹จ๊ณ„์˜ ์ตœ์ ํ•ด(์ž‘์€ ํ•˜์œ„ ๋ฌธ์ œ์˜ ํ•ด๋‹ต)๋ฅผ ์ด์šฉํ•ด ์ „์ฒด ๋ฌธ์ œ์˜ ์ตœ์ ํ•ด(ํฐ ๋ฌธ์ œ์˜ ํ•ด๋‹ต)๋ฅผ ๊ตฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋™์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

 

๋ฐ˜์‘ํ˜•