• 2020-12-17 买卖股票的最佳时机(含手续费)


    题目



    题解

    动态规划

    在每一天结束后,账户有两种股票的持有状态:持有与不持有。我们使用(dp[i][0])表示第(i+1)天结束后不持有股票的情况下的当前最大收益,使用(dp[i][1])表示第(i+1)天结束后持有股票的情况下的当前最大收益。

    • 对于(dp[i][0]),即第(i+1)天结束后不持有股票,若前一天不持有股票,则dp[i][0] = dp[i-1][0];若前一天持有股票,则表示当天将股票卖出,dp[i][0] = dp[i-1][1]+precise[i]-fee,二者选其大。

    [dp[i][0] = max(dp[i-1][0], dp[i-1][1]+precise[i]-fee) ]

    • 对于(dp[i][1]),即第(i+1)天结束后持有股票,若前一天不持有股票,则表示当天买入,dp[i][1] = dp[i-1][0]-precise[i];若前一天持有股票,则dp[i][1] = dp[i-1][1],二者选其大。

    [dp[i][1] = max(dp[i-1][1], dp[i-1][0]-precise[i]) ]

    在本题中,由于当天的状态只与前一天的状态有关,所以不需要维护(dp)这样一个二维数组,而只需使用两个变量(sell)(buy)来记录状态即可。

    class Solution {
    public:
        int maxProfit(vector<int>& prices, int fee) {
            int sell = 0, buy = -prices[0];
            int len = prices.size();
            for (int i = 1; i < len; ++i) {
                sell = max(sell, buy+prices[i]-fee);
                buy = max(buy, sell-prices[i]);
            }
    
            return sell;
        }
    };
    

    贪心法

    (buy)表示在利益最大的前提下,最低的买入价格+交易费用;初始情况buy = precise[0] + fee,在向后遍历的过程中可能遇到这几种情况:

    • buy > precise[i]+fee:即找到了更低的买入价格,使用precise[i]+fee替换buy
    • buy < precise[i]:即以当前价格卖出,即使加上手续费仍能盈利,应果断卖出。但是后续可能出现更高的股价,这时可以将buy置为precise[i],若后续出现更高的价格,比如下一天出现更高的价格,则profit += precise[i+1] - precise[i];
    • precise[i] + fee > buy > precise[i]:这种情况既不能卖出,也不能以更低的价格买入,不做操作。
    class Solution {
    public:
        int maxProfit(vector<int>& prices, int fee) {
            int profit = 0;
            int buy = prices[0] + fee;
            int len = prices.size();
            for (int i =1; i < len; ++i) {
                if (buy > prices[i] + fee) {
                    buy = prices[i] + fee;
                } else {
                    if (buy < prices[i]) {
                        profit += prices[i] - buy;
                        buy = prices[i];
                    }
                }
            }
    
            return profit;
        }
    };
    

    总结

    一看到题目就知道是动态规划,使用贪心也有机会解出来,但就是想不出状态转换方程,贪心的一些小细节也拿捏不准,最后还是看了题解才能做出来。

    CS专业在读,热爱编程。
    专业之外,喜欢阅读,尤爱哲学、金庸、马尔克斯。
  • 相关阅读:
    mysql的CURRENT_TIMESTAMP【转】
    php开发中emoji表情的问题3种方法轻松处理【转】
    JavaScript 正则表达式【转】
    使用 内置函数strtok()函数实现 loadrunner 字符串替换
    python打开文件失败,报错'gbk' codec can't decode byte 0xbf in position 2: illegal multibyte sequence
    txt文本程序 打开python文件 另存为原来的文件名,不能覆盖原来的文件解决
    linux 文件解压
    tar.xz 解压
    设置xampp开机自动启动
    Can’t connect to local MySQL server through socket的解决方法
  • 原文地址:https://www.cnblogs.com/jmhwsrr/p/14151812.html
Copyright © 2020-2023  润新知