算法Day50 | 123.买卖股票的最佳时机III,188.买卖股票的最佳时机IV

Day50

    • 123.买卖股票的最佳时机III
    • 188.买卖股票的最佳时机IV

123.买卖股票的最佳时机III

题目链接: 123.买卖股票的最佳时机III
与121. 买卖股票的最佳时机和122.买卖股票的最佳时机II一样,都需要dp数组来维护状态。

dp数组:
dp[i][0]表示第i天一次都不持有股票
dp[i][1]表示第i天第一次持有股票
dp[i][2]表示第i天第一次不持有股票
dp[i][3]表示第i天第二次持有股票
dp[i][4]表示第i天第二次不持有股票

递推公式
dp[i][0] = dp[i - 1][0]没有操作
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])i - 1天第一次持有,第i天不操作或者第i - 1天不持有,第i天买入
dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i])i - 1天第一次不持有,第i天不操作或者第i - 1天第一次持有,第i天第一次不持有
dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i])dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i])同理

初始化
dp[0][0] = 0
dp[0][1] = -prices[0]
dp[0][2] = 0同一天第一次持有,又第一次不持有 。服务于dp数组
dp[0][3] = -prices[0]dp[0][4] = 0同理

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

其实dp[i][0]一直是0,可以将dp[i][0]省略;同理于01背包,一维数组有如下代码:

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

188.买卖股票的最佳时机IV

题目链接:188.买卖股票的最佳时机IV
本题与上一题的唯一区别就是至多两次,变成至多k次。

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

你可能感兴趣的:(刷题日志,算法,数据结构,leetcode,动态规划,c++)