• 代码随想录day49:动态规划part10


    121.买卖股票的最佳时机

    贪心:

    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            int low = INT_MAX;
            int result = 0;
            for (int i = 0; i < prices.size(); i++) {
                low = min(low, prices[i]);  // 取最左最小价格
                result = max(result, prices[i] - low); // 直接取最大区间利润
            }
            return result;
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    动态规划
    1.dp数组的定义–dp[i][0]表示第i天持有股票所得最多现金,dp[i][1]表示第i天不持有股票所得最多现金。注意持有不等于第i天买入。
    2.递推公式:
    dp[i][0] = max(dp[i - 1][0], -prices[i])第i天持有股票可能是前一天就持有股票,也可能是今天刚买的股票
    dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);第i天不持有股票可能是昨天卖出的,也可能是今天卖出的。
    3.dp数组初始化:其基础都是要从dp[0][0]和dp[0][1]推导出来。
    第0天就持有股票,则就是第0天买入的。dp[0][0]=-price[0];
    第0天不持有股票,则还没开始买股票,dp[0][1]=0;
    4.遍历顺序:从前向后遍历。

    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            vector<vector<int>> dp(prices.size(),vector<int>(2,0));
            dp[0][0]=-prices[0];
            dp[0][1]=0;
            for(int i=1;i<prices.size();i++){
                dp[i][0]=max(dp[i-1][0],-prices[i]);//dp[i-1][1]-prices
                dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i]);
            }
            return dp[prices.size()-1][1];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    优化:从递推公式可以看出,dp[i]只是依赖于dp[i - 1]的状态。那么我们只需要记录 当前天的dp状态和前一天的dp状态就可以了,可以使用滚动数组来节省空间:

    class Solution {
    public:
        int maxProfit(vector<int>& prices) {
            vector<vector<int>> dp(2,vector<int>(2,0));
            dp[0][0]=-prices[0];
            dp[0][1]=0;
            for(int i=1;i<prices.size();i++){
                dp[i%2][0]=max(dp[(i-1)%2][0],-prices[i]);//dp[i-1][1]-prices
                dp[i%2][1]=max(dp[(i-1)%2][1],dp[(i-1)%2][0]+prices[i]);
            }
            return dp[(prices.size()-1)%2][1];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    买卖股票的最佳时机II

    与上一道题的区别:可以多次买卖一支股票,但必须在再次购买前出售掉之前的股票
    之前的贪心算法就用的这个例子讲的
    在这里插入图片描述这次动态规划的方法:
    1.dp数组的定义:dp[i][0] 表示第i天持有股票所得现金。dp[i][1] 表示第i天不持有股票所得最多现金
    2.递推公式:
    dp[i][0] = max(dp[i - 1][0], dp[i-1][1]-prices[i])第i天持有股票可能是前一天就持有股票,也可能是今天刚买的股票
    dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);第i天不持有股票可能是昨天卖出的,也可能是今天卖出的。
    3.dp数组初始化:其基础都是要从dp[0][0]和dp[0][1]推导出来。
    第0天就持有股票,则就是第0天买入的。dp[0][0]=-price[0];
    第0天不持有股票,则还没开始买股票,dp[0][1]=0;
    4.遍历顺序:从前向后遍历。

            vector<vector<int>> dp(2,vector<int>(2,0));
            dp[0][0]=-prices[0];
            dp[0][1]=0;
            for(int i=1;i<prices.size();i++){
                dp[i%2][0]=max(dp[(i-1)%2][0],dp[(i-1)%2][1]-prices[i]);//dp[i-1][1]-prices
                dp[i%2][1]=max(dp[(i-1)%2][1],dp[(i-1)%2][0]+prices[i]);
            }
            return dp[(prices.size()-1)%2][1];
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    pytorch的安装教程
    【读书笔记】【More Effective C++】操作符(Operators)
    【I/O方式——程序中断】
    22-07-27 西安 ElasticSearch(02)
    一份超预期的期中成绩,拨开百果园“高价值迷雾”
    安卓APP(1)——安卓工程构建和第一APP运行
    DevOps的出现带来的变化
    Docker容器化部署企业级应用集群
    100条安全原则来制定安全策略
    让我踩坑的超链接href属性
  • 原文地址:https://blog.csdn.net/qq_45789731/article/details/133277620