其他分享
首页 > 其他分享> > LeetCode309. 最佳买卖股票时机含冷冻期

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

作者:互联网

状态机dp,可以参考LeetCode188. 买卖股票的最佳时机 IV.

我们可以用一个数组dp[n][2]表示每一个状态下的最高收益(其中n是prices数组的大小,即总的天数)。
数组的第一维表示天数,第二维表示持有或不持有股票(1表示持有,0表示不持有)能获得的最大收益。
比如dp[i][0]表示第i天,不持有股票的最高收益,dp[i][1]表示第i天,持有股票的最高收益。

对于一个不持有股票的状态dp[i][0],它由两种状态转移而来,即(1)前一天也不持有股票,今天什么都没做,这种情况下我们有: dp[i][0] = dp[i - 1][0];
(2)前一天持有股票,今天把股票卖了,这种情况下我们有:dp[i][0] = dp[i - 1][1] + prices[i]; 加上prices[i]表示卖出股票增加了prices[i]的收益。
由于我们的dp数组表示的是某状态下的最高收益,因此我们需要对上面的两个状态取一个max: dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);

对于一个持有股票的状态dp[i][1],它也由两种状态转移而来,即(1)前一天就持有股票,今天什么都没做,这种情况下我们有: dp[i][1] = d[i - 1][1];
(2)前两天不持有股票,今天买了一只股票(由于有一天的交易冷冻期,所以不能是昨天买的股票,而是前天买的),这种情况下我们有: dp[i][1] = dp[i - 2][0] - prices[i];
减去prices[i]表示我们花了prices[i]的价格/成本买了一只股票。
由于我们的dp数组表示的是某状态下的最高收益,因此我们需要对上面的两个状态取一个max: dp[i][1] = max(dp[i - 1][1], dp[i - 2][0] - prices[i]);

有了状态转移方程,我们再考虑一下递推边界,由于状态转移方程中用到了dp[i - 1][]和dp[i - 2][],所以对于i为0和i为1的情况我们要单独处理,以防数组越界。

状态dp[0][0]表示第0天,不持有股票,显然dp[0][0] = 0;
状态dp[0][1]表示第0天,持有股票,也就是第0天花了prices[0]的价格买了一只股票,我们有:dp[0][1] = -prices[0];
状态dp[1][0]表示第1天,不持有股票,这有两种情况:(1)第0天和第1天什么都没做:dp[1][0] = 0; (2)第0天买入股票,第1天卖出: dp[0][1] = -prices[0] + prices[1];
同样的,状态要取两者中的较大值: dp[0][1] = max(0, -prices[0] + prices[1]);
状态dp[1][1]表示第1天,持有股票,这也有两种情况:(1)第0天买了只股票,第1天什么都没做:dp[1][1] = -prices[0]; (2)第0天什么都没做,第1天买了只股票:dp[1][1] = -prices[1];
同样的,状态要取两者中的较大值: dp[1][1] = max(-prices[0], -prices[1]);

有了递推边界和状态转移方程之后,我们就可以开始状态转移了。

最后的答案就是dp[n - 1][0],表示最后一天,不持有股票,所能获得的最高收益。
为什么不是dp[n - 1][1]呢?因为股票卖出去肯定比拿在手里的钱多,毕竟买股票要钱,交易掉还能赚差价呢。
所以显然dp[n - 1][0]的值大于dp[n - 1][1]。
最终答案就是dp[n - 1][0]。

代码如下:

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

标签:状态,持有,股票,LeetCode309,最佳,max,prices,冷冻,dp
来源: https://www.cnblogs.com/linrj/p/13458596.html