当前位置: 首页 > news >正文

Python动态规划:从基础到高阶优化的全面指南(2)

四、动态规划优化技巧

4.1 状态压缩:空间复杂度优化

滚动数组技巧

def knapsack_01_optimized(weights, values, capacity):n = len(weights)dp = [0] * (capacity+1)for i in range(n):# 逆序更新避免覆盖for w in range(capacity, weights[i]-1, -1):dp[w] = max(dp[w], dp[w-weights[i]] + values[i])return dp[capacity]

状态变量缩减

def max_subarray(nums):"""最大子数组和 - Kadane算法"""current_max = global_max = nums[0]for i in range(1, len(nums)):current_max = max(nums[i], current_max + nums[i])global_max = max(global_max, current_max)return global_max
4.2 记忆化搜索:自顶向下实现
from functools import lru_cachedef longest_increasing_subsequence(nums):@lru_cache(maxsize=None)def dp(i):"""以nums[i]结尾的最长递增子序列长度"""max_len = 1for j in range(i):if nums[j] < nums[i]:max_len = max(max_len, dp(j) + 1)return max_lenreturn max(dp(i) for i in range(len(nums)))# 测试
nums = [10, 9, 2, 5, 3, 7, 101, 18]
print(longest_increasing_subsequence(nums))  # 输出:4 (2,5,7,101)
4.3 斜率优化:时间复杂度优化
def max_profit_k_transactions(prices, k):"""股票买卖K次最大利润"""n = len(prices)if n < 2: return 0# 如果k过大,退化为贪心if k >= n//2:return sum(max(0, prices[i]-prices[i-1]) for i in range(1, n))# dp[i][j] 第i天完成j次交易的最大利润dp = [[0]*(k+1) for _ in range(n)]for j in range(1, k+1):# 优化:记录前一天的最大值pre_max = -prices[0]for i in range(1, n):# 状态转移方程dp[i][j] = max(dp[i-1][j], prices[i] + pre_max)pre_max = max(pre_max, dp[i][j-1] - prices[i])return dp[n-1][k]# 测试
prices = [3, 2, 6, 5, 0, 3]
print(max_profit_k_transactions(prices, 2))  # 输出:7 (2->6, 0->3)

五、动态规划在工程中的应用

5.1 自然语言处理:分词优化
def word_break(s, word_dict):"""单词拆分问题:判断字符串是否可分割"""n = len(s)# dp[i]表示s[0:i]是否可拆分dp = [False] * (n+1)dp[0] = Truefor i in range(1, n+1):for j in range(i):if dp[j] and s[j:i] in word_dict:dp[i] = Truebreakreturn dp[n]# 测试
s = "applepenapple"
word_dict = {"apple", "pen"}
print(word_break(s, word_dict))  # True
5.2 图像处理:最短路径识别
def min_path_sum(grid):"""网格最小路径和"""m, n = len(grid), len(grid[0])dp = [[0]*n for _ in range(m)]# 初始化dp[0][0] = grid[0][0]for i in range(1, m):dp[i][0] = dp[i-1][0] + grid[i][0]for j in range(1, n):dp[0][j] = dp[0][j-1] + grid[0][j]# 状态转移for i in range(1, m):for j in range(1, n):dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]return dp[m-1][n-1]# 测试
grid = [[1, 3, 1],[1, 5, 1],[4, 2, 1]
]
print(min_path_sum(grid))  # 输出:7 (1->3->1->1->1)
5.3 金融分析:期权定价
def option_pricing(S, K, T, r, sigma, N=1000):"""二叉树期权定价模型"""dt = T / N  # 时间步长u = np.exp(sigma * np.sqrt(dt))  # 上涨因子d = 1 / u  # 下跌因子p = (np.exp(r * dt) - d) / (u - d)  # 风险中性概率# 创建二叉树末节点价值values = np.zeros(N+1)for i in range(N+1):ST = S * (u ** i) * (d ** (N - i))values[i] = max(0, ST - K)  # 看涨期权# 反向递推计算当前价值for step in range(N-1, -1, -1):for i in range(step+1):values[i] = np.exp(-r * dt) * (p * values[i+1] + (1-p) * values[i])return values[0]# 测试
price = option_pricing(S=100, K=100, T=1, r=0.05, sigma=0.2)
print(f"期权理论价格: {price:.2f}")  # 约10.45

六、高阶动态规划技术

6.1 状态机动态规划
def max_profit_with_cool_down(prices):"""含冷冻期的股票买卖"""n = len(prices)if n < 2: return 0# 状态定义:# dp[i][0]: 持有股票# dp[i][1]: 不持有股票,处于冷冻期# dp[i][2]: 不持有股票,不处于冷冻期dp = [[0]*3 for _ in range(n)]# 初始化dp[0][0] = -prices[0]for i in range(1, n):# 状态转移dp[i][0] = max(dp[i-1][0], dp[i-1][2] - prices[i])dp[i][1] = dp[i-1][0] + prices[i]  # 卖出dp[i][2] = max(dp[i-1][1], dp[i-1][2])return max(dp[n-1][1], dp[n-1][2])# 测试
prices = [1, 2, 3, 0, 2]
print(max_profit_with_cool_down(prices))  # 输出:3 (1买,2卖,0买,2卖)
6.2 数位动态规划

def count_digit_one(n):"""计算1~n所有数字中1出现的次数"""s = str(n)@lru_cache(maxsize=None)def dp(pos, cnt, tight):"""递归函数pos: 当前处理位置cnt: 已计数1的个数tight: 是否受前导零限制"""if pos == len(s):return cntlimit = int(s[pos]) if tight else 9total = 0for digit in range(limit + 1):next_tight = tight and (digit == limit)next_cnt = cnt + 1 if digit == 1 else cnttotal += dp(pos+1, next_cnt, next_tight)return totalreturn dp(0, 0, True)# 测试
print(count_digit_one(13))  # 输出:6 (1,10,11,12,13)
6.3 树形动态规划
class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef rob_tree(root):"""二叉树房屋抢劫问题"""def dp(node):"""返回(偷当前节点的最大值, 不偷当前节点的最大值)"""if not node:return 0, 0left = dp(node.left)right = dp(node.right)# 偷当前节点:当前值 + 不偷子节点rob_curr = node.val + left[1] + right[1]# 不偷当前节点:取子节点最大值not_rob = max(left) + max(right)return rob_curr, not_robreturn max(dp(root))# 测试
#     3
#    / \
#   2   3
#    \   \ 
#     3   1
root = TreeNode(3)
root.left = TreeNode(2, None, TreeNode(3))
root.right = TreeNode(3, None, TreeNode(1))
print(rob_tree(root))  # 输出:7 (3+3+1)

http://www.lryc.cn/news/603013.html

相关文章:

  • 商用车的自动驾驶应用场景主要包括七大领域
  • 代码随想录算法训练营第三十三天
  • C++模板进阶:从基础到实战的深度探索
  • 网易易盾、腾讯ACE等主流10款游戏反外挂系统对比
  • 7寸工业模组 XA070Y2-L01芯显科技详细参数资料
  • 图——邻接表基本操作算法实现
  • USRP X410 X440 5G及未来通信技术的非地面网络(NTN)
  • 代码解读:微调Qwen2.5-Omni 实战
  • 《Go Web编程实战派--从入门到精通》的随笔笔记
  • LLM Landscape:2025年大语言模型概览
  • 数据处理工具是做什么的?常见数据处理方法介绍
  • ethers.js基础(学习路线清单)
  • 正向代理和反向代理的理解
  • 从“PPT动画”到“丝滑如德芙”——uni-app x 动画性能的“终极奥义”
  • AI 驱动、设施扩展、验证器强化、上线 EVM 测试网,Injective 近期动态全更新!
  • clock_getres系统调用及示例
  • PyTorch中flatten()函数详解以及与view()和 reshape()的对比和实战代码示例
  • 【代码解读】通义万相最新视频生成模型 Wan 2.2 实现解析
  • AR技术赋能工业设备维护:效率与智能的飞跃
  • 一个典型的微控制器MCU包含哪些模块?
  • 安宝特方案丨AI算法能力开放平台:适用于人工装配质检、点检、实操培训
  • Java学习-----如何创建线程
  • 基于黑马教程——微服务架构解析(二):雪崩防护+分布式事务
  • Qt:盒子模型的理解
  • 2025.7.28总结
  • 嵌入式分享合集186
  • JavaScript 回调函数讲解_callback
  • 关于xshell的一些基本内容讲解
  • tsc命令深入全面讲解
  • jQuery 最新语法大全详解(2025版)