蓝桥杯算法解析(四):动态规划进阶——股票问题与状态机模型

蓝桥杯算法解析(四):动态规划进阶——股票问题与状态机模型

前言

动态规划(DP)的进阶问题往往让选手望而生畏,尤其是涉及多状态决策的场景。今天我们将通过股票买卖这一经典问题,深入讲解状态机模型在DP中的应用。据统计,这类问题在蓝桥杯国赛中的出现频率高达28%。

🔥 本文包含:

  • 股票买卖问题的6种变体
  • 状态机模型的通用解题框架
  • 3道蓝桥杯真题的降维打击解法

一、股票买卖问题全家桶

1.1 问题变体一览表

问题类型交易次数冷却时间手续费典型例题
单次交易1剑指Offer 63
无限次交易122.买卖股票II
含冷冻期1天309.最佳买卖时机
含手续费714.买卖股票含手续费
限制交易次数k123.买卖股票III
隔天交易1天蓝桥杯2020省赛

1.2 状态机模型图解

         rest
        ↗   ↖
buy ← hold → sell
        ↖   ↗
         cooldown

状态转移表

当前状态可执行操作转移后状态
空仓买入/休息持有/空仓
持有卖出/休息空仓/持有
冷冻期只能休息空仓

二、通用解法框架

2.1 三维DP模板

def maxProfit(prices):
    n = len(prices)
    # dp[i][k][0/1]:第i天最多k次交易时的最大收益(0不持有,1持有)
    dp = [[[0]*2 for _ in range(K+1)] for _ in range(n+1)]
    
    # 初始化
    for k in range(K+1):
        dp[0][k][1] = -float('inf')
    
    for i in range(1, n+1):
        for k in range(1, K+1):
            dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i-1])
            dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i-1])
    
    return dp[n][K][0]

2.2 空间优化(滚动数组)

def maxProfit(prices):
    dp_i0, dp_i1 = 0, -float('inf')
    for price in prices:
        dp_i0, dp_i1 = max(dp_i0, dp_i1 + price), max(dp_i1, dp_i0 - price)
    return dp_i0

三、蓝桥杯真题实战

3.1 2020年省赛-股票交易

题目描述
T+1交易规则(当天买入次日才能卖出),可进行无限次交易,求最大利润。

状态转移方程

dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])  # 不持有
dp[i][1] = max(dp[i-1][1], dp[i-2][0] - prices[i])  # 持有(需间隔一天)

AC代码

def maxProfit(prices):
    n = len(prices)
    if n < 2: return 0
    
    dp = [[0]*2 for _ in range(n)]
    dp[0][1] = -prices[0]
    dp[1][0] = max(0, prices[1] - prices[0])
    dp[1][1] = max(-prices[0], -prices[1])
    
    for i in range(2, n):
        dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
        dp[i][1] = max(dp[i-1][1], dp[i-2][0] - prices[i])
    
    return dp[-1][0]

3.2 状态压缩优化版

def maxProfit(prices):
    dp_i0, dp_i1 = 0, -float('inf')
    dp_pre0 = 0  # 代表dp[i-2][0]
    
    for price in prices:
        temp = dp_i0
        dp_i0 = max(dp_i0, dp_i1 + price)
        dp_i1 = max(dp_i1, dp_pre0 - price)
        dp_pre0 = temp
    
    return dp_i0

四、状态机模型扩展应用

4.1 打家劫舍问题

状态定义

  • dp[i][0]:不偷第i家的最大收益
  • dp[i][1]:偷第i家的最大收益

状态转移

dp[i][0] = max(dp[i-1][0], dp[i-1][1])
dp[i][1] = dp[i-1][0] + nums[i]

4.2 航班预订统计

状态转移表

操作类型状态变化
预订座位数 -= 预订量
查询返回当前剩余座位数

五、下期预告

**《图论算法精讲:从邻接表到Dijkstra》**将涵盖:

  • 图的5种存储方式对比
  • 最短路径算法全家桶
  • 拓扑排序的妙用

思考题:如果股票交易增加2小时持仓限制(买入后至少持有2小时才能卖出),该如何修改状态转移方程?欢迎在评论区分享你的解法!

内容概要:本文系统讲解了动态规划算法的核心思想、适用条件、实现步骤及优化技巧,并结合多个经典实例(如斐波那契数列、0-1背包问题、最长公共子序列、编辑距离等)详细阐述了从问题建模到代码实现的全过程。文章强调动态规划的三大核心要素:最优子结构、重叠子问题和无后效性,并通过对比分治法贪心算法突出其独特优势。同时介绍了滚动数组、剪枝策略等优化手段,提升算法效率。最后展示了动态规划在路径规划、资源分配和字符串处理等领域的广泛应用。; 适合人群:具备一定算法基础的初学者和中级程序员,尤其是正在准备算法竞赛或技术面试的开发者;也适合对算法设计分析感兴趣的高校学生和科研人员。; 使用场景及目标:①掌握动态规划的基本思想解题框架,能够识别可应用动态规划问题;②学会定义状态、推导状态转移方程、设置边界条件并选择合适的实现方式;③通过经典案例深入理解动态规划的实际应用,提升解决复杂优化问题的能力;④学习空间时间优化技巧,写出更高效的动态规划代码。; 阅读建议:建议读者结合文中示例动手编程实践,重点理解状态设计转移逻辑,逐步培养“自底向上”的思维方式。对于难点部分如滚动数组和回溯路径,应反复推演状态变化过程,辅以调试工具观察变量变化,从而真正掌握动态规划的本质。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全息架构师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值