• Day41 力扣动态规划 :121. 买卖股票的最佳时机|122.买卖股票的最佳时机II


    详细布置

    股票问题是一个动态规划的系列问题,今日安排的题目不多,大家可以慢慢消化。

    121. 买卖股票的最佳时机

    视频讲解:https://www.bilibili.com/video/BV1Xe4y1u77q
    https://programmercarl.com/0121.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BA.html

    第一印象

    感觉股票问题不简单

    这道题一眼就可以暴力算,但是怎么dp呢。

    如果dp数组含义是: 第i天卖出的最大价值dp[i] ,感觉也是很暴力算法啊。

    直接看题解吧

    看完题解的思路

    太有难度啦

    dp数组

    dp[i][0] 表示第i天持有股票所得最多现金 ,dp[i][1] 表示第i天不持有股票所得最多现金

    注意这里说的是“持有”,“持有”不代表就是当天“买入”!也有可能是昨天就买入了,今天保持持有的状态

    递推公式

    如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来

    • 第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]
    • 第i天买入股票,所得现金就是买入今天的股票后所得现金即:-prices[i]

    dp[i][0]应该选所得现金最大的,所以dp[i][0] = max(dp[i - 1][0], -prices[i]);

    如果第i天不持有股票即dp[i][1], 也可以由两个状态推出来

    • 第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][1]
    • 第i天卖出股票,所得现金就是按照今天股票价格卖出后所得现金即:prices[i] + dp[i - 1][0]

    同样dp[i][1]取最大的,dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);

    这样递推公式我们就分析完了

    因为每一天都是 买或不买 和 卖或不卖。

    如果已经买了,就不可能再买,就要保持原状;还没买就可以买入。这两种选一个最大的

    如果已经卖了,就不可能再卖,就要保持原状;还没卖就可以卖掉。这两种选一个最大的。

    初始化

    第一天不持有是0,持有是 -price

    遍历顺序

    就是正序遍历

    实现中的困难

    对于 i 天持有的情况,比较的是 i - 1 持有的价格和 -price

    而不是 i - 1 不持有 - price。

    因为只买卖一次,一开始净收入 0 ,第一次买入就是 -price

    感悟

    股票问题感觉就是状态很多

    代码

    class Solution {
        public int maxProfit(int[] prices) {
            //dp[i][0] 第i天不持有
            //dp[i][1] 第i天持有
            int[][] dp = new int[prices.length][2];
    
            //初始化
            dp[0][0] = 0;
            dp[0][1] = -prices[0];
    
            //递推公式
            for (int i = 1; i < dp.length; i++) {
                //这一天不持有的话
                dp[i][0] =  Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
                //这一天持有的话
                dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);
            }
            return dp[dp.length - 1][0];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    122.买卖股票的最佳时机II

    视频讲解:https://www.bilibili.com/video/BV1D24y1Q7Ls
    https://programmercarl.com/0122.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BAII%EF%BC%88%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%EF%BC%89.html

    第一印象

    直接看题解,这道题是可以反复买卖这只股票。

    看完题解的思路

    其实就是我做股票1的时候写错的那部分哈哈哈

    实现中的困难

    感悟

    代码

    class Solution {
        public int maxProfit(int[] prices) {
            //dp[i][0] 第i天不持有
            //dp[i][1] 第i天持有
            int[][] dp = new int[prices.length][2];
    
            //初始化
            dp[0][0] = 0;
            dp[0][1] = -prices[0];
    
            //递推公式
            for (int i = 1; i < dp.length; i++) {
                //这一天不持有的话
                dp[i][0] =  Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
                //这一天持有的话
                dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
            }
            return dp[dp.length - 1][0];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    基于linux的聊天功能设计与实现
    字符设备驱动框架(字符设备基础一)
    推荐算法——自动特征交叉
    Spring AOP
    聊聊今年测试秋招情况......
    SpringBoot与Loki的那些事
    关于java多线程的一些知识点
    Maven发布自己项目到maven中央仓库
    C++ YAML使用
    Go十大常见错误第9篇:使用文件名称作为函数输入
  • 原文地址:https://blog.csdn.net/leeBerson/article/details/134077499