算法学习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
    • dp[i][0]
      • 如果当天未买入, 那就延续i-1[0]的值
      • 如果当天买入了, 那值就是 - price[i]
      • 取最大值
    • dp[i][1]
      • 如果当天未卖出, 那就延续i-1[1]的值
      • 如果当天卖出了, 那值就= i-1[0] + price[i]
    • dp[i][2]
      • 如果当天未买入, 那就延续i-1[2]的值
      • 如果当天买入了, 那值就是[i-1][1] - price[i]
    • dp[i][3]
      • 如果当天未买入, 那就延续i-1[3]的值
      • 如果当天卖出了, 那值就是[i-1][2] + price[i]
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];
}
相关推荐
DevangLic15 分钟前
github学生认证怎么搞
学习
夜瞬16 分钟前
NLP学习笔记13:BERT系列模型——从预训练到 RoBERTa 与 ALBERT
笔记·学习·自然语言处理
Polaris_T26 分钟前
2026最新字节大模型岗面经汇总(多平台整理)
人工智能·经验分享·算法·aigc·求职招聘
Don.TIk32 分钟前
原理的学习
学习
ghie909035 分钟前
MATLAB 解线性方程组的迭代法
开发语言·算法·matlab
m0_7431064636 分钟前
【浙大&南洋理工最新综述】Feed-Forward 3D Scene Modeling(二)
人工智能·算法·计算机视觉·3d·几何学
Brilliantwxx37 分钟前
【数据结构】排序算法的神奇世界(下)
c语言·数据结构·笔记·算法·排序算法
进击的荆棘37 分钟前
递归、搜索与回溯——二叉树中的深搜
数据结构·c++·算法·leetcode·深度优先·dfs
人道领域40 分钟前
【LeetCode刷题日记】:151翻转字符串的单词(两种解法)
java·开发语言·算法·leetcode·面试
会编程的土豆1 小时前
【日常做题】栈 中缀前缀后缀
开发语言·数据结构·算法