zoukankan      html  css  js  c++  java
  • 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专业在读,热爱编程。
    专业之外,喜欢阅读,尤爱哲学、金庸、马尔克斯。
  • 相关阅读:
    hdu1151 二分图(无回路有向图)的最小路径覆盖 Air Raid
    二分图多重匹配问题
    二分图最大匹配问题及其扩展
    ZOJ3741 状压DP Eternal Reality
    POJ2699:The Maximum Number of Strong Kings(枚举+贪心+最大流)
    POJ2396:Budget(带下界的网络流)
    POJ2391:Ombrophobic Bovines(最大流+Floyd+二分)
    POJ1637:Sightseeing tour(混合图的欧拉回路)
    URAL1277 Cops and Thieves(最小割)
    Leetcode 44. Wildcard Matching
  • 原文地址:https://www.cnblogs.com/jmhwsrr/p/14151812.html
Copyright © 2011-2022 走看看