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

在这里插入图片描述

1、动态规划法

我们可以使用数组dp记录每天买卖股票可以获得的最大利润,其中针对买卖股票的不同状态有三种情况:1、我们拥有股票但未卖出,此时我们可能是从两种状态转移来的,一是前一天也持有未售出的股票;二是前一天刚刚结束未持有股票的状态,并刚刚购买了股票,因此为了获得当前的最大利润,我们可以得到状态转移公式为 d p [ i ] [ 0 ] = m a x ( d p [ i − 1 ] [ 0 ] , d p [ i − 1 ] [ 2 ] − p r i c e s [ i ] ) dp[i][0] = max(dp[i - 1][0], dp[i - 1][2] - prices[i]) dp[i][0]=max(dp[i1][0],dp[i1][2]prices[i]);2、我们未持有股票并处于冷冻期,此时我们只有可能是从一种状态转移过来的,就是前一天刚刚出售了股票,我们可以得到状态转移公式为 d p [ i ] [ 1 ] = d p [ i − 1 ] [ 0 ] + p r i c e s [ i ] dp[i][1] = dp[i - 1][0] + prices[i] dp[i][1]=dp[i1][0]+prices[i];3、我们未持有股票并不处于冷冻期,此时我们可能是从两种状态转移过来的:一是我们昨天处于冷冻期;二是我们昨天也没有持有股票,我们可以得到状态转移公式为 d p [ i ] [ 2 ] = m a x ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 2 ] ) dp[i][2] = max(dp[i - 1][1], dp[i - 1][2]) dp[i][2]=max(dp[i1][1],dp[i1][2])。最终我们为了获得最大利润,只需要比较 d p [ p r i c e s . s i z e ( ) − 1 ] [ 1 ] , d p [ p r i c e s . s i z e ( ) − 1 ] [ 2 ] dp[prices.size() - 1][1], dp[prices.size() - 1][2] dp[prices.size()1][1],dp[prices.size()1][2]中的最大值即可。

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

2、动态规划法优化

考虑到我们虽然占用了一个二维数组,但我们实际上使用的只有昨天的最大利润,因此我们可以使用三个变量来代替二维数组。

class Solution {
public:
    int maxProfit(vector<int> &prices) {
        if (prices.size() == 0 || prices.size() == 1) return 0;
        int profit_1 = -prices[0];
        int profit_2 = 0;
        int profit_3 = 0;
        for (int i = 1; i < prices.size(); ++i) {
            int temp_profit_1 = max(profit_1, profit_3 - prices[i]);
            int temp_profit_2 = profit_1 + prices[i];
            int temp_profit_3 = max(profit_2, profit_3);
            profit_1 = temp_profit_1;
            profit_2 = temp_profit_2;
            profit_3 = temp_profit_3;
        }
        return max(profit_2, profit_3);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值