zoukankan      html  css  js  c++  java
  • LeetCode714. 买卖股票的最佳时机含手续费

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

    我们有两个状态,当前交易的天数i和当前是否持有股票,我们用一个二维数组dp[n][2]表示各个状态所能获得的最大收益(其中n为prices数组的大小,表示交易的天数)。
    比如dp[i][0]表示第i天(i从0开始),当前不持有股票(第二维0表示不持有股票,1表示持有股票)所能获得的最大收益。
    dp[i][1]表示第i天(i从1开始),当前持有股票所能获得的最大收益。

    我们考虑一个不持有股票的状态dp[i][0], 不持有股票有两种情况:(1)前一天也不持有股票,然后今天啥也没做,这种情况下收益和前一天是相同的。这种情况下我们有:dp[i][0] = dp[i - 1][0];
    (2)前一天持有股票,今天卖掉了,这种情况下我们有:dp[i][0] = dp[i - 1][1] + 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] = dp[i - 1][1];
    (2)前一天不持有股票,今天买了一只股票,这种情况下我们有:dp[i][1] = dp[i - 1][1] - prices[i] - fee; 其中减去prices[i]和fee表示第i天以prices[i]的价格买了股票,并交了价格为fee
    的手续费。
    由于dp数组表示的是某个状态下的最大收益,因此我们需要对上面两种状态取一个max,所以我们有:dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i] - fee);

    现在我们有了状态转移方程,由于状态转移的过程中计算dp[i][]需要用到状态dp[i - 1][],当i为0时会导致数组越界,所以我们需要对边界情况特殊处理一下。

    dp[0][0]表示第0天,不持有股票所能获得的最大收益,显然dp[0][0] = 0;
    dp[0][1]表示第0天,持有股票所能获得的最大收益,显然第0天要持有股票只能第0天买了,要交第0天股票的价格,还有手续费。所以我们有dp[0][1] = -prices[0] - fee;

    有了状态表示、处理了递归边界、推导出了状态转移方程,就可以开始状态转移了。

    最后的答案就是dp[n - 1][0],表示最后一天,不持有股票所能获得的最高收益。
    为什么不是dp[n - 1][1]呢?因为买股票需要成本(股票本身的价格以及手续费),股票卖出去能够获得收入,所以dp[n - 1][0]的值大于dp[n - 1][1]。

    代码如下:

    class Solution {
    public:
        int maxProfit(vector<int>& prices, int fee) {
            int n = prices.size();
            vector<vector<int>> dp(n, vector<int>(2));
            for(int i = 0; i < n; ++i) {
                if(i == 0) {                        //递推边界
                    dp[i][0] = 0;
                    dp[i][1] = -prices[i] - fee;
                    continue;
                }
                dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);            //状态转移
                dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i] - fee);
            }
            return dp[n - 1][0];
        }
    };
    
  • 相关阅读:
    jquery validate 自定义验证方法 日期验证
    转:前端控制器是邪恶的么?
    eclipse打开文件位置Open Explorer 插件
    Eclipse标准版安装J2EE
    短网址生成思路算法
    smarty模板执行原理
    Smarty 变量使用
    Php模板引擎Smarty安装和配置
    转:PHP分页技术的代码和示例
    黑板架构模式及其常见实现方式
  • 原文地址:https://www.cnblogs.com/linrj/p/13460609.html
Copyright © 2011-2022 走看看