首页 > 编程语言 >算法刷题 Day 50 | ● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV

算法刷题 Day 50 | ● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV

时间:2023-02-22 15:22:15浏览次数:70  
标签:买卖 50 E6% vector 最佳时机 prices dp

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

这道题一下子就难度上来了,关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖。

视频讲解:https://www.bilibili.com/video/BV1WG411K7AR

https://programmercarl.com/0123.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAIII.html

Tips:dp每个时间节点从两个状态变为了5个状态

我的题解:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        // 0:没有操作 (其实我们也可以不设置这个状态)
        // 1:第一次持有股票
        // 2:第一次不持有股票
        // 3:第二次持有股票
        // 4:第二次不持有股票
        vector<vector<int>> dp(prices.size(),vector<int>(5,0));
        dp[0][1] = -prices[0];
        dp[0][3] = -prices[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]);
        }
        
        // 现金最大的时候一定是卖出的状态,而两次卖出的状态现金最大一定是最后一次卖出。
        // 如果想不明白的录友也可以这么理解:如果第一次卖出已经是最大值了,
        // 那么我们可以在当天立刻买入再立刻卖出。所以dp[4][4]已经包含了dp[4][2]的情况。
        // 也就是说第二次卖出手里所剩的钱一定是最多的。
        
        // int maxValue = 0;
        // for(int i = 0; i< 5;i++){
        //     maxValue = max(dp[prices.size()-1][i],maxValue);
        // }

        return dp[prices.size()-1][4];
    }
};

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

本题是123.买卖股票的最佳时机III 的进阶版

视频讲解:https://www.bilibili.com/video/BV16M411U7XJ

https://programmercarl.com/0188.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAIV.html

Tips:把上一题的思路扩展到k个即可,其实就是加个循环。如果有k次买入卖出的话,对应的就是2k个状态(买入一个状态,卖出一个状态)。

我的题解:

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        // k笔交易就需要2k个状态,买入卖出各一个
        vector<vector<int>> dp(prices.size(),vector<int>(2*k,0));
        // 先对所有买入状态进行初始化
        for(int i = 0; i<2*k; i = i+2){
            dp[0][i] = -prices[0];
        }

        // 更新dp数组
        for(int i = 1; i<prices.size(); i++){
            dp[i][0] = max(dp[i-1][0], 0 - prices[i]);
            for(int j = 1; j<2*k; j++){
                if(j%2==1){
                    dp[i][j] = max(dp[i-1][j], dp[i-1][j-1] + prices[i]);
                }
                else{
                    dp[i][j] = max(dp[i-1][j], dp[i-1][j-1] - prices[i]);
                }
            }
        }
        return dp[prices.size()-1][2*k-1];
    }
};

标签:买卖,50,E6%,vector,最佳时机,prices,dp
From: https://www.cnblogs.com/GavinGYM/p/17144513.html

相关文章