代码随想录算法训练营第51天|309.最佳买卖股票时机含冷冻期,714.买卖股票的最佳时机含手续费

代码随想录算法训练营第51天|309.最佳买卖股票时机含冷冻期,714.买卖股票的最佳时机含手续费

  • 309.最佳买卖股票时机含冷冻期
  • 714.买卖股票的最佳时机含手续费

309.最佳买卖股票时机含冷冻期

题目链接:309.最佳买卖股票时机含冷冻期,难度:中等
【实现代码】

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.size() == 1) {
            return 0;
        }
        vector<vector<int>> dp(prices.size(), vector<int>(2, 0));
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        dp[1][0] = max(dp[0][0], -prices[1]);
        dp[1][1] = max(dp[0][0] + prices[1], dp[0][1]);
        for (int i = 2; i < prices.size(); i++) {
            dp[i][0] = max(dp[i - 1][0], dp[i - 2][1] - prices[i]);
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
        }
        return dp.back().back();
    }
};

【解题思路】

动规五部曲,分析如下:

  1. 确定dp数组以及下标的含义
    dp[i][0]为第i天持有股票时的最多现金;dp[i][1]为第i天不持有股票时的最多现金。
  2. 确定递推公式:
    达到dp[i][0]状态,有两个具体操作:
    操作一:第i天买入股票了,那就意味着需要从第i-2天不持有股票了,那么dp[i][0] = dp[i-2][1] - prices[i]
    操作二:第i天没有操作,而是沿用前一天买入的状态,即:dp[i][0] = dp[i - 1][0]
    一定是选最大的,所以 dp[i][0] = max(dp[i - 1][0], dp[i - 2][1] - prices[i]);
    同理dp[i][1]也有两个操作:
    操作一:第i天卖出股票了,那么dp[i][1] = dp[i - 1][0] + prices[i]
    操作二:第i天没有操作,沿用前一天卖出股票的状态,即:dp[i][1] = dp[i - 1][1]
    所以dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
  3. dp数组如何初始化:
    dp[0][0] = -prices[0];
    dp[0][1] = 0;
    dp[1][0] = max(dp[0][0], -prices[1]); //因为没有一天的冷冻期
    dp[1][1] = max(dp[0][0] + prices[1], dp[0][1]);
  4. 确定遍历顺序
    从递归公式上可以看出,dp[i] 依赖于 dp[i-1],所以是从前向后遍历。
  5. 举例推导dp数组

714.买卖股票的最佳时机含手续费

题目链接:714.买卖股票的最佳时机含手续费,难度:中等
【实现代码】

class Solution {
public:
    int maxProfit(vector<int>& prices, int fee) {
        if (prices.size() == 1) {
            return 0;
        }
        vector<vector<int>> dp(prices.size(), vector<int>(2, 0));
        dp[0][0] = -prices[0];
        for (int i = 1; i < prices.size(); i++) {
            dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);
        }
        return dp.back().back();
    }
};

【解题思路】

动规五部曲,分析如下:

  1. 确定dp数组以及下标的含义
    dp[i][0]为第i天持有股票时的最多现金;dp[i][1]为第i天不持有股票时的最多现金。
  2. 确定递推公式:
    达到dp[i][0]状态,有两个具体操作:
    操作一:第i天买入股票了,那就意味着需要从第i-1天不持有股票了,那么dp[i][0] = dp[i-1][1] - prices[i]
    操作二:第i天没有操作,而是沿用前一天买入的状态,即:dp[i][0] = dp[i - 1][0]
    一定是选最大的,所以 dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
    同理dp[i][1]也有两个操作:
    操作一:第i天卖出股票了,卖出时需要扣除手续费,那么dp[i][1] = dp[i - 1][0] + prices[i] - fee
    操作二:第i天没有操作,沿用前一天卖出股票的状态,即:dp[i][1] = dp[i - 1][1]
    所以dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);
  3. dp数组如何初始化:
    dp[0][0] = -prices[0];
    dp[0][1] = 0;
  4. 确定遍历顺序
    从递归公式上可以看出,dp[i] 依赖于 dp[i-1],所以是从前向后遍历。
  5. 举例推导dp数组

你可能感兴趣的:(算法基础,算法,动态规划,leetcode)