zoukankan      html  css  js  c++  java
  • 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];
        }
    };
    
  • 相关阅读:
    Ubuntu配置sublime text 3的c编译环境
    ORA-01078错误举例:SID的大写和小写错误
    linux下多进程的文件拷贝与进程相关的一些基础知识
    ASM(四) 利用Method 组件动态注入方法逻辑
    基于Redis的三种分布式爬虫策略
    Go语言并发编程总结
    POJ2406 Power Strings 【KMP】
    nyoj 会场安排问题
    Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor.
    Java的String、StringBuffer和StringBuilder的区别
  • 原文地址:https://www.cnblogs.com/linrj/p/13458596.html
Copyright © 2011-2022 走看看