动态规划DP入门详解(从原理到实战,新手必看)

动态规划入门详解(从原理到实战,新手必看)

动态规划问题(Dynamic Programming,简称DP)应该是很多读者头疼的,但这类问题也是最具技巧性、最有意思的。动态规划作为运筹学的一种最优化方法,在计算机算法中应用广泛,比如最长递增子序列、最小编辑距离等经典问题,都离不开动态规划的思想。

本文将彻底解决三个核心问题,帮你打通动态规划的任督二脉:

  • 动态规划到底是什么?
  • 解决动态规划问题有什么固定技巧?
  • 新手该如何高效学习动态规划?

刷题刷多了就会发现,算法技巧就那几个套路。后续的动态规划系列文章,都会围绕本文的解题框架展开,掌握了这套思路,再难的DP问题也能迎刃而解。所以本文作为DP入门第一章,希望能成为你解决动态规划问题的指导方针,下面直接上干货!

一、动态规划的核心本质

首先明确:动态规划问题的一般形式就是求最值。无论是最长、最小、最多、最少,只要题目要求“最值”,大概率就是动态规划问题。

既然是求最值,核心问题是什么?答案很简单:穷举。因为要找最值,必须先把所有可行的答案穷举出来,再从里面筛选出最值。

看到这里你可能会疑惑:动态规划不就是穷举吗?为什么我遇到的DP问题都那么难?

其实难的不是穷举本身,而是如何“聪明地穷举”——动态规划的穷举,需要满足两个前提,还要掌握一个核心技巧:

  1. 最优子结构:原问题的最值,可以通过子问题的最值推导得到(子问题之间互相独立,无相互制约);
  2. 重叠子问题:暴力穷举会重复计算大量相同子问题,效率极低,需要通过“备忘录”或“DP table”优化;
  3. 状态转移方程:这是DP的核心,也是最难的一步,它定义了“如何通过子问题推导原问题”,本质就是穷举的规则。

重叠子问题、最优子结构、状态转移方程,就是动态规划的三要素。其中,写出状态转移方程是重中之重。

DP解题思维框架(必背)

为了帮你快速梳理状态转移方程,我总结了一套固定思维框架,按步骤走,就能逐步推出解法:

  1. 定义dp数组及下标含义;
  2. 确定递归公式(状态转移);
  3. 初始化dp数组;
  4. 确定遍历顺序;
  5. 举例推导dp数组;

掌握这个框架后,DP解法的代码就会呈现出固定模板,分为两种形式:

1. 自顶向下递归(带备忘录)
# 自顶向下递归的动态规划defdp(状态1, 状态2,...):for 选择 in 所有可能的选择:# 此时的状态已经因为做了选择而改变 result = 求最值(result, dp(状态1, 状态2,...))return result 
2. 自底向上迭代(DP table)
# 自底向上迭代的动态规划# 初始化 base case(最基础、无需推导的子问题) dp[0][0][...]= base case# 进行状态转移(从base case逐步推导到原问题)for 状态1in 状态1的所有取值: for 状态2in 状态2的所有取值: for... dp[状态1][状态2][...]= 求最值(选择1,选择2...)

下面通过两个经典案例,详解动态规划的三要素和解题框架——斐波那契数列(理解重叠子问题)、凑零钱问题(掌握状态转移方程)。

二、案例一:斐波那契数列(理解重叠子问题)

力扣第509题「斐波那契数」,是理解重叠子问题的最佳案例。请不要嫌弃它简单,简单案例才能让你集中精力关注算法背后的思想,而非复杂细节。

说明:斐波那契数列严格来说不是动态规划问题(因为没有求最值),但它的递归结构中存在大量重叠子问题,是讲解“优化重叠子问题”的绝佳例子。

1. 暴力递归(低效版)

斐波那契数列的数学递归公式为:f(n) = f(n-1) + f(n-2),base case为f(0)=0、f(1)=1(力扣题目定义)。

直接翻译成代码如下:

 # 计算第n个斐波那契数 intfib(int n){ // base case:最基础的子问题,直接返回结果if(n ==0|| n ==1){ return n;}// 递归推导:原问题 = 子问题1 + 子问题2returnfib(n -1)+fib(n -2);}
低效原因:大量重叠子问题

假设n=20,画出递归树就能发现问题:要计算f(20),需要先算f(19)和f(18);要算f(19),需要先算f(18)和f(17)……以此类推。

其中,f(18)被计算了两次,f(17)被计算了三次,且以f(18)为根的递归树体量巨大,重复计算会耗费大量时间。

时间复杂度分析
  • 子问题个数:递归树是一棵高度为n的二叉树,节点总数为O(2ⁿ)(指数级别);
  • 单个子问题时间:仅一个加法操作,O(1);
  • 总时间复杂度:O(2ⁿ),指数爆炸,效率极低。

2. 带备忘录的递归(优化重叠子问题)

既然低效的原因是重复计算,那就用一个「备忘录」,记录已经计算过的子问题答案。每次遇到子问题,先查备忘录,有结果直接用,无结果再计算并存入备忘录。

备忘录可以用一维数组(适合子问题是单个整数的情况)或哈希表实现,这里用一维数组更高效。

#include<vector>usingnamespace std;intfib(int n){ 

Read more

基于 Python 与 GitHub,打造个人专属本地化思维导图工具全流程方案(上)

基于 Python 与 GitHub,打造个人专属本地化思维导图工具全流程方案(上)

基于 Python 与 GitHub,打造个人专属本地化思维导图工具全流程方案(上) 各位博友,自从踏入修真界,就整天想怎样把代码改造成绝世技能。这不又有新思路,准备用 Python 和 GitHub 这两把 “趁手仙器”,从零开始打造一个专属于自己的本地化思维导图工具。 这工具啥特色?轻量到能揣兜里跑(内存占用低),颜值随你心意改(界面可自定义),还能离线玩得转(数据全存本地)。不管你是想理清楚小说剧情线、课堂笔记,还是规划个小项目,它都能支棱起来。咱不整那些花里胡哨的框架套路,就靠最基础的 HTML/CSS/JS 和 Python,一步步带你打通 “开发任督二脉”:从拆解开源项目优点,到写代码时的 “挖坑填坑”,再到最后打包成能双击运行的 EXE 文件,每一步都给你掰扯得明明白白。 放心,就算你是刚摸到键盘的 “练气期” 萌新,跟着咱的节奏走,也能亲手造出趁手的

By Ne0inhk
豆包    Linux源码下载全方案(官方+国内镜像+Git,含校验与Windows兼容)

豆包 Linux源码下载全方案(官方+国内镜像+Git,含校验与Windows兼容)

一、官方tar包下载(推荐,稳定快速) 1. 选择版本(访问kernel.org) * 主线版mainline:最新开发版(如6.19-rc5),适合尝鲜 * 稳定版stable:经测试稳定(如6.19.0),适合开发 * 长期支持版longterm:长期维护(如6.12.65、6.6.120),适合生产 2. 下载步骤(以6.6.120为例) bash 安装依赖(Ubuntu/Debian) sudo apt update && sudo apt install -y wget xz-utils gpg 下载源码包和校验文件

By Ne0inhk
2026全球开源大模型TOP10榜单+主流模型深度解析

2026全球开源大模型TOP10榜单+主流模型深度解析

【前言】2026年,开源大模型迎来爆发式发展,中国力量持续领跑,MoE架构成为绝对主流,模型发展从“通用全能”向“场景专精”深度转型。本文结合Hugging Face最新榜单及权威机构评估,整理出2026年全球开源大模型TOP10排行榜,深度解析主流模型的技术亮点、性能表现与适用场景,并从技术架构、训练数据、指令遵循、微调能力四大维度,全面评估当前开源大模型的技术发展水平,为开发者选型、企业落地提供参考。 一、2026全球开源大模型TOP10排行榜 本次榜单基于下载量、LMSYS盲测、工程化落地成本、商用友好度、社区活跃度五大核心维度,结合Hugging Face最新发布的开源大模型榜单及多个权威评测机构综合评估整理而成,覆盖全球主流开源模型,精准反映当前开源大模型的综合竞争力。 排名 模型名称 机构 架构 核心参数 主打能力 适用场景 1 Qwen 3.5 阿里 MoE 397B 总 / 17B 激活

By Ne0inhk