代码随想录算法训练营29期|day54 任务以及具体安排

第九章 动态规划part11

  • 123.买卖股票的最佳时机III

    java 复制代码
    // 版本一
    class Solution {
        public int maxProfit(int[] prices) {
            int len = prices.length;
            // 边界判断, 题目中 length >= 1, 所以可省去
            if (prices.length == 0) return 0;
    
            /*
             * 定义 5 种状态:
             * 0: 没有操作, 1: 第一次买入, 2: 第一次卖出, 3: 第二次买入, 4: 第二次卖出
             */
            int[][] dp = new int[len][5];
            dp[0][1] = -prices[0];
            // 初始化第二次买入的状态是确保 最后结果是最多两次买卖的最大利润
            dp[0][3] = -prices[0];
    
            for (int i = 1; i < len; i++) {
                dp[i][1] = Math.max(dp[i - 1][1], -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]);
                dp[i][4] = Math.max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
            }
    
            return dp[len - 1][4];
        }
    }

    思路:于上两个股票买卖问题的区别在于这道题限制了买卖次数,需要定义五种状态:0、1、2、3、4来代表不同的状态。然后使用递推公式对dp数组进行更新。

  • 188.买卖股票的最佳时机IV

    java 复制代码
    // 版本一: 三维 dp数组
    class Solution {
        public int maxProfit(int k, int[] prices) {
            if (prices.length == 0) return 0;
    
            // [天数][交易次数][是否持有股票]
            int len = prices.length;
            int[][][] dp = new int[len][k + 1][2];
            
            // dp数组初始化
            // 初始化所有的交易次数是为确保 最后结果是最多 k 次买卖的最大利润
            for (int i = 0; i <= k; i++) {
                dp[0][i][1] = -prices[0];
            }
    
            for (int i = 1; i < len; i++) {
                for (int j = 1; j <= k; j++) {
                    // dp方程, 0表示不持有/卖出, 1表示持有/买入
                    dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]);
                    dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]);
                }
            }
            return dp[len - 1][k][0];
        }
    }
    
    // 版本二: 二维 dp数组
    class Solution {
        public int maxProfit(int k, int[] prices) {
            if (prices.length == 0) return 0;
    
            // [天数][股票状态]
            // 股票状态: 奇数表示第 k 次交易持有/买入, 偶数表示第 k 次交易不持有/卖出, 0 表示没有操作
            int len = prices.length;
            int[][] dp = new int[len][k*2 + 1];
            
            // dp数组的初始化, 与版本一同理
            for (int i = 1; i < k*2; i += 2) {
                dp[0][i] = -prices[0];
            }
    
            for (int i = 1; i < len; i++) {
                for (int j = 0; j < k*2 - 1; j += 2) {
                    dp[i][j + 1] = Math.max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]);
                    dp[i][j + 2] = Math.max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);
                }
            }
            return dp[len - 1][k*2];
        }
    }

    思路:该题与上题的区别在于该题是至多能k次,所以二维数组需要2*k+1的维度,1、3、5等奇数代表持有股票,2、4、6等偶数代表不持有股票。然后根据递推公式进行遍历递推。再进行dp数组的初始化。

相关推荐
短剑重铸之日9 分钟前
《ShardingSphere解读》07 读写分离:如何集成分库分表+数据库主从架构?
java·数据库·后端·架构·shardingsphere·分库分表
知我Deja_Vu10 分钟前
【避坑指南】ConcurrentHashMap 并发计数优化实战
java·开发语言·python
2401_8318249620 分钟前
基于C++的区块链实现
开发语言·c++·算法
We་ct27 分钟前
LeetCode 918. 环形子数组的最大和:两种解法详解
前端·数据结构·算法·leetcode·typescript·动态规划·取反
愣头不青31 分钟前
238.除了自身以外数组的乘积
数据结构·算法
人工智能AI酱1 小时前
【AI深究】逻辑回归(Logistic Regression)全网最详细全流程详解与案例(附大量Python代码演示)| 数学原理、案例流程、代码演示及结果解读 | 决策边界、正则化、优缺点及工程建议
人工智能·python·算法·机器学习·ai·逻辑回归·正则化
WangLanguager1 小时前
逻辑回归(Logistic Regression)的详细介绍及Python代码示例
python·算法·逻辑回归
m0_518019481 小时前
C++与机器学习框架
开发语言·c++·算法
一段佳话^cyx1 小时前
详解逻辑回归(Logistic Regression):原理、推导、实现与实战
大数据·算法·机器学习·逻辑回归
qq_417695051 小时前
C++中的代理模式高级应用
开发语言·c++·算法