算法学习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];
}
相关推荐
OYangxf1 分钟前
力扣hot100【子串专题】
算法·leetcode·职场和发展
小新同学^O^4 分钟前
简单学习 --> 数据加密
java·数据库·学习·数据加密
AOwhisky6 分钟前
Docker 学习笔记:从生态系统到镜像构建
linux·运维·笔记·学习·docker·容器
WL_Aurora7 分钟前
Python 算法基础篇之元组与列表
python·算法
知识分享小能手7 分钟前
R语言入门学习教程,从入门到精通,R语言数据结构(4)
数据结构·学习·r语言
Brilliantwxx8 分钟前
【算法题】递归树+哈希表+分治异或+双指针
开发语言·c++·笔记·算法
yugi9878389 分钟前
经典三维表面重建算法(C语言实现)
c语言·开发语言·算法
无限进步_11 分钟前
【C++】智能指针族谱:auto_ptr、unique_ptr、shared_ptr
java·开发语言·数据结构·c++·算法
Brilliantwxx12 分钟前
【C++】Stack和Queue(初认识和算法题OJ)
开发语言·c++·笔记·算法
fffzd16 分钟前
C++入门(二)
开发语言·c++·算法·函数重载·引用·inline内联函数·nullptr