1. 动态规划基础概念动态规划(Dynamic Programming, DP)是一种用于解决复杂问题的算法设计技术特别适用于具有重叠子问题和最优子结构特性的问题。我第一次接触DP是在解决斐波那契数列问题时当时被它高效的记忆化能力所震撼。DP的核心思想是将原问题分解为相对简单的子问题通过存储子问题的解来避免重复计算。这与分治法类似但关键区别在于DP会利用记忆化存储来优化性能。举个例子计算斐波那契数列时朴素递归会有O(2^n)的时间复杂度而DP版本只需O(n)。2. DP问题特征分析2.1 最优子结构一个问题具有最优子结构性质意味着问题的最优解包含其子问题的最优解。比如在经典的背包问题中要确定是否将当前物品放入背包需要先知道剩余容量下的最优解。2.2 重叠子问题在递归解决方案中相同的子问题会被反复计算。DP通过记忆化存储这些子问题的解来提升效率。例如在计算斐波那契数列时fib(3)会被多次计算。3. DP解题步骤详解3.1 定义状态状态表示是DP的核心。以01背包问题为例我们定义dp[i][j]表示考虑前i个物品在背包容量为j时的最大价值。状态定义的好坏直接影响问题解决的难易程度。3.2 状态转移方程这是DP的灵魂所在。对于背包问题状态转移方程为 dp[i][j] max(dp[i-1][j], dp[i-1][j-w[i]] v[i]) 其中w[i]和v[i]分别表示第i个物品的重量和价值。3.3 初始化边界条件正确的初始化至关重要。在背包问题中dp[0][j] 0没有物品时价值为0dp[i][0] 0容量为0时价值为0。3.4 确定计算顺序通常采用自底向上的方式计算。对于背包问题我们通常先遍历物品再遍历容量。4. 经典DP问题解析4.1 01背包问题这是最基础的DP问题之一。实际编码时可以采用空间优化将二维数组降为一维数组def knapsack(W, wt, val, n): dp [0]*(W1) for i in range(n): for j in range(W, wt[i]-1, -1): dp[j] max(dp[j], dp[j-wt[i]]val[i]) return dp[W]4.2 最长公共子序列(LCS)LCS问题的状态转移方程很有代表性if text1[i-1] text2[j-1]: dp[i][j] dp[i-1][j-1] 1 else: dp[i][j] max(dp[i-1][j], dp[i][j-1])4.3 矩阵链乘法这个问题展示了DP在优化计算顺序上的应用。状态转移方程为dp[i][j] min(dp[i][k] dp[k1][j] p[i-1]*p[k]*p[j] for k in range(i,j))5. DP优化技巧5.1 空间优化很多DP问题可以将二维数组优化为一维数组。关键是要注意遍历顺序避免覆盖还需要使用的数据。5.2 状态压缩对于某些问题可以用位运算来压缩状态。这在状压DP中很常见。5.3 单调队列优化适用于特定形式的状态转移方程可以将时间复杂度从O(n^2)降到O(n)。6. DP问题实战心得6.1 如何识别DP问题我总结的经验是当问题可以分解为子问题且子问题有重叠时考虑DP。特别是求极值、计数类问题DP往往是好选择。6.2 调试DP代码的技巧打印DP表格是最有效的调试方法。对于二维DP我习惯用以下方式打印for row in dp: print( .join(f{x:2} for x in row))6.3 常见错误分析初始化不正确特别是边界条件的处理遍历顺序错误特别是在空间优化后状态转移方程考虑不全面遗漏某些情况7. 树形DP与状压DP7.1 树形DP实现要点树形DP通常采用后序遍历的方式。以二叉树最大路径和为例def maxPathSum(root): res -float(inf) def dfs(node): nonlocal res if not node: return 0 left max(dfs(node.left), 0) right max(dfs(node.right), 0) res max(res, left right node.val) return max(left, right) node.val dfs(root) return res7.2 状压DP应用场景状压DP常用于解决排列组合问题特别是当状态可以用二进制表示时。例如旅行商问题(TSP)dp [[float(inf)] * n for _ in range(1n)] dp[1][0] 0 for mask in range(1n): for u in range(n): if mask (1u): for v in range(n): if not mask (1v): dp[mask|(1v)][v] min(dp[mask|(1v)][v], dp[mask][u] dist[u][v])8. 区间DP与数位DP8.1 区间DP模板区间DP通常用于解决分段问题如石子合并n len(stones) prefix [0]*(n1) for i in range(n): prefix[i1] prefix[i] stones[i] dp [[0]*n for _ in range(n)] for length in range(2, n1): for i in range(n-length1): j i length - 1 dp[i][j] float(inf) for k in range(i, j): dp[i][j] min(dp[i][j], dp[i][k] dp[k1][j] prefix[j1] - prefix[i])8.2 数位DP实现方法数位DP常用于数字计数问题。以计算1到n中数字1出现的次数为例def countDigitOne(n): s str(n) lru_cache(maxsizeNone) def dp(pos, cnt, tight): if pos len(s): return cnt limit int(s[pos]) if tight else 9 res 0 for d in range(limit 1): new_tight tight and (d limit) new_cnt cnt (d 1) res dp(pos 1, new_cnt, new_tight) return res return dp(0, 0, True)9. DP与其他算法的结合9.1 DP与贪心算法有些问题可以先用贪心缩小范围再用DP求解。例如部分背包问题。9.2 DP与图论最短路径问题中的Floyd算法本质上是DPfor k in range(n): for i in range(n): for j in range(n): dist[i][j] min(dist[i][j], dist[i][k] dist[k][j])9.3 DP与数据结构使用线段树等数据结构可以优化某些DP问题的状态转移过程。10. 动态规划实战建议在实际应用中我建议从以下几个方面提升DP能力多练习经典问题如背包、LCS、编辑距离等总结常见状态定义方式如序列问题常用dp[i]区间问题常用dp[i][j]掌握空间优化技巧特别是滚动数组和状态压缩学会打印和调试DP表格这是理解DP过程的最佳方式尝试用不同角度思考状态定义有时候换个角度定义状态会使问题更简单记住DP能力的提升需要大量练习。我建议按照类型系统性地刷题从简单到困难逐步深入。每次遇到新的DP变种都尝试总结其特点和解题模式。
企业数字化 ERP 产品动态
相关推荐
物联网技术架构与行业应用深度解析 1. 物联网技术架构解析 物联网系统通常采用三层或四层架构设计。三层架构由下至上分别为感测层、网络层和应用层;四层架构则进一步将应用层拆分为平台工具层和应用服务层,这种划分能更精细地管理软件组件。在实际工业场景中,四层架构的采用率… · 2026/11/3 18:40:45
libcurl 7.40 Windows预编译包VS工程接入与排错 简介:这是一份面向 Windows 平台 C/C 开发者的 libcurl 7.40 预编译依赖包,适合需要在 Visual Studio 各版本中快速接入 HTTP/HTTPS 请求、又不想自行处理 OpenSSL、zlib、libssh2 等依赖编译的开发者。压缩包共 17 个文件,约 1.23MB… · 2026/11/2 15:56:24
从马尔可夫链到隐马尔可夫模型:序列建模的核心概念与工程判断 简介:围绕模式识别核心知识整理的PPT课件,面向人工智能、机器学习初学者及需要补充概率模型基础的读者,重点解决马尔科夫模型与隐马尔科夫模型概念抽象、公式与实例难以对应的问题。课件从马尔可夫性、马尔科夫链及转移概率矩阵讲起ÿ… · 2026/11/3 20:19:41
hindsight:基于Python+Docker的可观测性因果推理系统 1. 项目概述:hindsight 不是“事后诸葛亮”,而是一套可落地的工程化复盘系统“hindsight”这个词在日常语境里常被译作“后见之明”,带点调侃意味——事情办砸了,才恍然大悟“早该这么干”。但在我过去八年做技术基建、AI工具链和… · 2026/11/3 22:15:07
Paperclip:React前端零侵入接入Claude/OpenClaw的AI运行时胶合层 1. 项目概述:Paperclip 是什么?它解决的不是“又一个前端框架”问题Paperclip 这个名字乍一听容易让人联想到办公用品——回形针,但放在当前技术语境下,它绝不是个玩笑或占位符。结合高频热搜词Node.js、React、OpenClaw、Claude的… · 2026/11/3 22:15:07
军训工作总结PPT改造指南:五段式结构、数据图表与交付自检 简介:这份PPT面向企业行政、人力资源及培训管理人员,围绕企业军训活动的总结汇报场景,提供一套可直接参考的演示文稿范例,帮助解决汇报结构松散、成果与问题梳理不系统等问题。压缩包内共1个pptx文件,大小约4.71MB&… · 2026/11/3 22:15:07
Lambda架构在智慧城市中的实践与优化 1. 智慧城市建设中的数据困局与破局思路三年前我参与某省会城市交通大脑项目时,第一次深刻体会到"数据烟囱"的破坏力——交管局卡口数据用Oracle存储、公交集团的GPS轨迹存在HBase、地铁票务系统跑在MySQL上。当我们需要预测节假日客流时,竟要… · 2026/11/3 22:15:07
如何写出高价值总结:信息压缩与知识传递的工程化方法 1. 为什么“总结”这件事值得单独拎出来聊干了十来年项目,我发现一个挺有意思的现象:几乎所有人都觉得“总结”这事儿没什么技术含量,无非是把做过的事情再复述一遍,写个文档交差。可真到了要复盘、要汇报、要交接、要沉淀方法论的… · 2026/11/3 22:15:07
AI工程基座构建:Python+TypeScript+Rust+Julia协同实践 1. 为什么“从零构建AI工程体系”不是口号,而是当下最真实的生存需求最近帮三个不同行业的团队做技术栈复盘,发现一个扎心的共性:他们都有“AI项目”,但没有“AI工程”。有人用Jupyter跑通了一个LSTM预测模型,部署时卡… · 2026/11/3 22:14:06
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46