• 代码随想录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
  • 相关阅读:
    【JavaScript复习十】数组入门知识
    【AI视野·今日Sound 声学论文速览 第二十六期】Mon, 16 Oct 2023
    11-标准库fmt以及文件操作
    PS不能完成命令,因为没有足够内存(RAM)
    Java 基础 进程与线程
    一种用于环境声源的被动到达角(AoA)提取算法(Matlab代码实现)
    c++ 正则表达式
    使用jmeter+ant进行接口自动化测试(数据驱动)
    【浅学Java】SpringBoot创建和使用
    基于 C# 实现样式与数据分离的打印方案
  • 原文地址:https://blog.csdn.net/qq_45789731/article/details/133277620