zoukankan      html  css  js  c++  java
  • [LintCode 1691.] 买卖股票的最佳时机V

    LintCode 1691. 买卖股票的最佳时机V

    题目描述

    给出一个股票n天的价格,每天最多只能进行一次交易,可以选择买入一支股票或卖出一支股票或放弃交易,输出能够达到的最大利润值

    样例

    样例 1:

    给出 a = [1,2,10,9], 返回 16
    输入:
    [1,2,10,9]
    输出:
    16
    解释:
    你可以在第一天和第二天买入股票,第三天和第四天卖出
    利润:-1-2+10+9 = 16
    样例 2:

    给出 a = [9,5,9,10,5], 返回 5
    输入:
    [9,5,9,10,5]
    输出:
    5
    解释:
    你可以在第2天买入,第4天卖出
    利润:-5 + 10 = 5

    注意事项

    1 ≤ n ≤ 10000

    解题思路

    这道股票买卖问题,与以往的限制一次买卖、限制两次买卖、限制k次买卖、限制卖出后才能下一次买入……都不同,并不限制持有的股票数量,可以随时买入卖出。
    这里直接使用状态转移方程,每一天有3个状态:买入、卖出、无操作。
    使用dp[i][j]表示第i天持有j只股票的最大收益,则 dp[i][j] = max(dp[i-1][j-1]-a[j-1], dp[i-1][j+1]+a[j-1], dp[i-1][j])

    参考代码

    class Solution {
    public:
        /**
         * @param a: the array a
         * @return: return the maximum profit
         */
        int getAns(vector<int> &a) {
            // write your code here
            if (a.size() <= 1) return 0;
    
            size_t n = a.size();
            vector<vector<int>> dp(n+1, vector<int>(n+1)); // 前 i 天进行 j 次买卖的最大利润
            for (int i=0; i<n; i++) {
                dp[i][0] = 0;
                dp[0][i] = 0;
            }
            for (int i=1; i<=n; i++) {
                dp[i][0] = std::max(dp[i-1][0], dp[i-1][1]+a[i-1]);
                dp[i][i] = dp[i-1][i-1] - a[i-1];
                dp[i][i-1] = std::max(dp[i-1][i-1], dp[i-1][i-2] - a[i-1]);
                for (int j=1; j<=i-2; j++) {
                    dp[i][j] = max3(
                        dp[i-1][j],         // 不操作
                        dp[i-1][j-1]-a[i-1],// 买入
                        dp[i-1][j+1]+a[i-1] // 卖出
                        );
                }
            }
            int res = 0;
            for (int j=0; j<n; j++) {
                res = std::max(res, dp[n][j]);
            }
            return res;
        }
        static inline int max3(int a, int b, int c) {
            int m = a > b ? a : b;
            return m > c ? m : c;
        }
    };
    

    minor fix:

    • if(i>=2) dp[i][i-1] = std::max(dp[i-1][i-1], dp[i-1][i-2] - a[i-1]);
    • 不从dp[n]中选最大值,直接return dp[n][0];
  • 相关阅读:
    [bzoj1934][Shoi2007]Vote 善意的投票
    [bzoj1834][ZJOI2010]network 网络扩容
    [bzoj2127]happiness
    [bzoj3876][Ahoi2014]支线剧情
    [bzoj1927][Sdoi2010]星际竞速
    [bzoj3223]Tyvj 1729 文艺平衡树
    [bzoj3224]Tyvj 1728 普通平衡树
    FJOI2017 RP++
    [bzoj3529][Sdoi2014]数表
    异步ajax请求数据处理
  • 原文地址:https://www.cnblogs.com/zhcpku/p/14261598.html
Copyright © 2011-2022 走看看