算法学习day41-动态规划

买卖股票

核心思路

  • 这道题的核心思路是动态规划,定义一个二维数组 dp[i][j],其中 i 表示第 i 天,j 表示是否持有股票(0 表示持有,1
    表示不持有)。通过状态转移方程来更新这个数组,从而得到最大利润。
  • 状态转移方程如下:
    • dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i]):第 i 天持有股票的最大利润
      • 有两个推导逻辑
        1. 第 i-1 天已经持有股票,那么第 i 天继续持有,利润不变,即 dp[i-1][0]
        2. 第 i-1 天不持有股票,那么第 i 天买入股票,利润变为 -prices[i]
    • dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i]):第 i 天不持有股票的最大利润
      • 有两个推导逻辑
        1. 第 i-1 天已经不持有股票,那么第 i 天继续不持有,利润不变,即 dp[i-1][1]
        2. 第 i-1 天持有股票,那么第 i 天卖出股票,利润变为 dp[i-1][0] + prices[i]
  • 最终答案是 dp[n-1][1],即最后一天不持有股票的最大利润。

代码实现

java 复制代码
public static int maxProfit(int[] prices) {
    //dp[i][0]: 下标为i的时候, 持有股票 赚的钱
    //持有股票: 要么i-1就已经持有了, 要么i买入
    //dp[i][1]: 下标为i的时候, 未持有, 那就延续i-1的, 如果持有, 就卖掉, 就是i-1[0] - price[i]
    //
    int[][] dp = new int[prices.length][2];
    dp[0][0] = -prices[0];
    dp[0][1] = 0;
    for (int i = 1; i < prices.length; i++) {
        dp[i][0] = Math.max(dp[i - 1][0], -prices[i]);
        dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
    }
    return Math.max(dp[prices.length - 1][0], dp[prices.length - 1][1]);
}

买卖股票2

核心思路

  • 同买卖股票逻辑
  • 只是当计算持有的时候, 如果选择买入当天的, 需要用i-11减去i, 因为昨天是有可能有利润的
java 复制代码
    public static int maxProfit1(int[] prices) {
    int[][] dp = new int[prices.length][2];
    dp[0][0] = -prices[0];
    dp[0][1] = 0;
    for (int i = 1; i < prices.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[prices.length - 1][1];
}

买卖股票3

核心思路

  • 这道题可以买卖两次
    • 总结一下, 每天一共有4种状态
      1. 第一次持有或买进
      2. 第一次未持有或卖出
      3. 第二次持有或买进
      4. 第二次未持有或卖出
    • 递推dp
    • dpi0
      • 如果当天未买入, 那就延续i-10的值
      • 如果当天买入了, 那值就是 - pricei
      • 取最大值
    • dpi1
      • 如果当天未卖出, 那就延续i-11的值
      • 如果当天卖出了, 那值就= i-10 + pricei
    • dpi2
      • 如果当天未买入, 那就延续i-12的值
      • 如果当天买入了, 那值就是i-11 - pricei
    • dpi3
      • 如果当天未买入, 那就延续i-13的值
      • 如果当天卖出了, 那值就是i-12 + pricei
java 复制代码
public static int maxProfit2(int[] prices) {
    int[][] dp = new int[prices.length][4];
    dp[0][0] = -prices[0];
    dp[0][1] = 0;
    dp[0][2] = -prices[0];
    dp[0][3] = 0;
    for (int i = 1; i < prices.length; i++) {
        dp[i][0] = Math.max(dp[i - 1][0], -prices[i]);
        dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
        dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1] - prices[i]);
        dp[i][3] = Math.max(dp[i - 1][3], dp[i - 1][2] + prices[i]);
    }
    return dp[prices.length - 1][3];
}
相关推荐
I_belong_to_jesus9 小时前
C++关于分支预测的优化1
开发语言·c++·算法
Rabitebla11 小时前
【Linux】进程控制(十二) 自定义 Shell(二):内建命令与进程工作目录管理
linux·c++·笔记·学习·bash
Gary移动存储固件11 小时前
eMMC5.1协议中文学习讲解(6.6.17~6.6.22.4.6)
学习·ufs·emmc·nand·存储固件
一个天蝎座 白勺 程序猿12 小时前
别让收藏夹替你学习:我搭AI知识体系的完整方法,脚本直接拿去用
人工智能·学习·ai·ai学习
楚山之石13 小时前
【Nat Biomed Eng】Connectome 2.0 超高梯度扫描仪:500 mT/m 与 600 T/m/s 把活体人脑微观结构分辨推进到亚微米级
图像处理·学习·数据分析·mri
坤坤子吖15 小时前
Linux网络编程:TCP 粘包与半包问题,如何正确处理 TCP 流式数据?
linux·服务器·网络·笔记·网络协议·学习
Code_Solitude16 小时前
C语言动态内存 + 柔性数组 + 数组名退化
c语言·算法·柔性数组
上海潭龙东海科技有限公司17 小时前
客运站管控之动态孪生技术方案(新增一屏管控模块
数据仓库·人工智能·算法·重构·动态规划
YLCHUP19 小时前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论