λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸƒ algorithm/leetcode

LeetCode 309 - Best Time to Buy and Sell Stock with Cooldown (Medium)

by HandHand 2021. 3. 4.

문제

LeetCode - 309번

풀이 κ³Όμ •

νŠΉμ • 날에 주식을 맀도 ν˜Ήμ€ λ§€μˆ˜ν•˜μ—¬ 얻을 수 μžˆλŠ” μ΅œλŒ€ μ΄μœ€μ„ κ³„μ‚°ν•˜λŠ” 동적 κ³„νšλ²• λ¬Έμ œμž…λ‹ˆλ‹€.

문제 μ‘°κ±΄μ—μ„œ 주식을 ꡬ맀 μ „μ—λŠ” 판맀λ₯Ό λ¨Όμ € ν•΄μ•Όν•œλ‹€λŠ” 것이 λͺ…μ‹œλ˜μ–΄ μžˆλ‹€λŠ” 점에 μœ μ˜ν•©λ‹ˆλ‹€.

λ§Œμ•½ dp(i, buy) = i 번째 λ‚  μ£Όμ‹μ˜ 판맀 μƒνƒœκ°€ buy 일 λ•Œ i 이후 얻을 수 μžˆλŠ” μ΅œλŒ€ 이윀 이라고 μ •μ˜ν•œλ‹€λ©΄
λ‹€μŒκ³Ό 같은 점화식을 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

dp(i, buy) = max(dp(i+1, true) - stock[i], dp(i+1, false)), if buy == false
else(buy == true), dp(i, buy) = max(dp(i+2, false) + stock[i], dp(i+1, true))


즉, `i` 번째 λ‚  주식을 κ΅¬λ§€ν•œ μƒνƒœλΌλ©΄ ν•΄λ‹Ή 주식을 κ·Έλ‚  νŒλ§€ν•˜λŠ” 것과 νŒλ§€ν•˜μ§€ μ•Šκ³  λ‹€μŒ λ‚ λ‘œ λ„˜μ–΄κ°€λŠ” 경우λ₯Ό 비ꡐ해주고
λ°˜λŒ€λ‘œ κ΅¬λ§€ν•˜μ§€ μ•Šμ€ μƒνƒœλΌλ©΄ `i` 번째 λ‚  κ΅¬λ§€ν•˜κ±°λ‚˜ κ΅¬λ§€ν•˜μ§€ μ•Šκ³  λ„˜μ–΄κ°€λŠ” 것을 κ³ λ €ν•΄μ„œ μ΅œλŒ€ μ΄μœ€μ„ κ΅¬ν•©λ‹ˆλ‹€.

μ½”λ“œ

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function (prices) {
  const memo = new Array(prices.length)
    .fill(0)
    .map((_) => new Array(2).fill(-1));

  function dp(i, buy) {
    if (i >= prices.length) return 0;

    if (memo[i][buy] !== -1) return memo[i][buy];

    if (!buy) memo[i][buy] = Math.max(dp(i + 1, 1) - prices[i], dp(i + 1, 0));
    else memo[i][buy] = Math.max(dp(i + 2, 0) + prices[i], dp(i + 1, 1));

    return memo[i][buy];
  }

  const answer = dp(0, 0);
  return answer;
};
λ°˜μ‘ν˜•

πŸ’¬ λŒ“κΈ€