动态规划解决股票交易最大利润问题

📅 发布时间:2026/9/11 11:46:23
动态规划解决股票交易最大利润问题
1. 问题背景与核心挑战股票交易时机选择一直是量化投资领域的经典难题。这道题目的核心在于给定一个整数数组 prices 表示某只股票连续几天的价格你最多可以完成 k 笔交易买入和卖出算一次交易设计算法计算你能获得的最大利润。这个问题的难点在于交易次数的限制k次增加了状态转移的复杂度不能同时参与多笔交易必须在再次购买前出售掉之前的股票需要处理k值较大的情况当k≥n/2时实际上等同于无限次交易2. 动态规划解法详解2.1 状态定义我们使用三维动态规划来解决这个问题dp[i][k][0] 表示第i天结束时最多进行了k次交易手中没有股票时的最大利润dp[i][k][1] 表示第i天结束时最多进行了k次交易手中持有股票时的最大利润2.2 状态转移方程基础状态dp[0][k][0] 0 第0天未持有dp[0][k][1] -prices[0] 第0天持有转移方程dp[i][k][0] max(dp[i-1][k][0], dp[i-1][k][1] prices[i])dp[i][k][1] max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])2.3 空间优化由于每天的状态只依赖前一天的状态可以将空间复杂度从O(nk)优化到O(k)def maxProfit(k, prices): if not prices: return 0 n len(prices) if k n//2: # 等同于无限次交易的情况 return sum(max(prices[i1]-prices[i],0) for i in range(n-1)) dp [[[0]*2 for _ in range(k1)] for __ in range(n)] for i in range(n): for j in range(1, k1): if i 0: dp[i][j][0] 0 dp[i][j][1] -prices[i] continue dp[i][j][0] max(dp[i-1][j][0], dp[i-1][j][1]prices[i]) dp[i][j][1] max(dp[i-1][j][1], dp[i-1][j-1][0]-prices[i]) return dp[-1][k][0]3. 关键优化点分析3.1 交易次数k的处理当k≥n/2时问题退化为无限次交易的情况可以直接使用贪心算法求解if k n//2: profit 0 for i in range(1, n): if prices[i] prices[i-1]: profit prices[i] - prices[i-1] return profit3.2 边界条件处理需要特别注意以下边界条件空价格列表直接返回0单日价格无法完成交易返回0k0时无法交易返回04. 复杂度分析时间复杂度常规情况O(nk)当k≥n/2时O(n)空间复杂度未优化版本O(nk)优化版本O(k)5. 实际应用中的注意事项在真实交易系统中需要考虑交易手续费的影响可以在状态转移时扣除手续费对于高频交易场景k值可能非常大需要特别注意内存使用该算法假设可以准确知道未来价格实际应用中需要结合预测模型可以扩展该算法支持做空操作通过增加状态维度来实现6. 算法扩展与变种6.1 含交易手续费只需在卖出时扣除手续费dp[i][k][0] max(dp[i-1][k][0], dp[i-1][k][1]prices[i]-fee)6.2 冷冻期限制加入一天冷冻期买入时只能从前两天的状态转移dp[i][k][1] max(dp[i-1][k][1], dp[i-2][k-1][0]-prices[i])6.3 多支股票选择可以扩展为三维动态规划增加股票选择维度但复杂度会显著增加7. 测试用例设计好的测试用例应该包含常规情况k小于n/2边界情况k0k≥n/2极端情况价格单调增/减随机波动情况示例测试用例test_cases [ (2, [3,2,6,5,0,3], 7), # 常规 (2, [1,2,4], 3), # 价格单调增 (1, [7,6,4,3,1], 0), # 价格单调减 (100, [1,2,3,4,5], 4), # k≥n/2 (0, [1,2,3,4,5], 0) # k0 ]8. 常见错误与调试技巧数组越界确保所有索引访问都在有效范围内初始化错误特别注意第0天的初始化状态转移错误仔细检查买入和卖出时的状态转移条件空间优化时的覆盖问题注意更新顺序避免覆盖未使用的数据调试建议打印每天的状态表格从小规模测试用例开始验证使用断言检查不变性条件9. 性能优化实践对于大规模数据优先处理k≥n/2的特殊情况使用滚动数组优化空间对于固定k值可以预先分配内存考虑并行计算不同k值的情况10. 与其他股票问题的对比这个问题是股票买卖系列问题中最通用的形式当k1时退化为单次交易问题当k∞时退化为无限次交易问题当加入冷冻期、手续费等限制时成为变种问题理解这个通用解法后其他股票问题都可以视为其特例或扩展。