深入浅出动态规划:从基础到蓝桥杯实战(Java版)
引言:为什么你需要掌握动态规划?
动态规划(DP)是算法竞赛和面试中的常客,不仅能大幅提升解题效率(时间复杂度通常为O(n)或O(n²))[4],更是解决复杂优化问题的利器。统计显示,蓝桥杯、LeetCode等竞赛中30%以上的难题都可采用DP解决[2]。本文将用最通俗易懂的方式带你掌握DP精髓!
一、动态规划本质解密
类比理解:想象你正在写作业,遇到不会的题,你会先解出简单题,记下解法(备忘录),遇到类似难题直接套用,这就是DP的核心。
三大特征:
- 重叠子问题:如同斐波那契数列中fib(5)需要多次计算fib
- 最优子结构:全局最优解包含局部最优解(如最短路径的子路径也最短)
- 状态转移:当前状态只依赖前面有限个状态
与贪心算法区别:
- 贪心:局部最优→全局最优(不保证全局最优)
- DP:考虑所有可能性→确保全局最优[1]
二、DP两大实现范式 (代码对比)
1. 自底向上(表格法)
// 斐波那契数列示例
int fib(int n) {int[] dp = new int[n+2]; // 防御性编程dp[0] = 0; dp[1] = 1; // base casefor (int i = 2; i <= n; i++) {dp[i] = dp[i-1] + dp[i-2]; // 状态转移}return dp[n];
}
✔️ 效率高(O(n))
✔️ 避免递归栈溢出
✖️ 需要想清楚填表顺序
2. 自顶向下(记忆化搜索)
int[] memo = new int[100]; // 记忆数组
int fib(int n) {if (n <= 1) return n;if (memo[n] != 0) return memo[n]; // 已计算memo[n] = fib(n-1) + fib(n-2); // 递归计算return memo[n];
}
✔️ 更符合直觉
✔️ 只计算必要子问题
✖️ 递归深度受限
三、DP四步解题法(重点!)
- 定义状态 💡
-
- 明确dp[i]或dp[i][j]的含义
- 示例:爬楼梯问题中dp[i]表示到第i阶的方法数
- 状态转移方程 📝
-
- 分析状态之间的关系
- 斐波那契:dp[i] = dp[i-1] + dp[i-2]
- 初始化 🔨
-
- 设置边界条件
- dp[0] = 1, dp[1] = 1
- 确定计算顺序 ➡️
-
- 自底向上:从dp[0]开始正向计算
- 自顶向下:递归+记忆化
案例实战:爬楼梯问题(每次1/2阶)
int climbStairs(int n) {if (n <= 2) return n;int[] dp = new int[n+1];dp[0] = 1; dp[1] = 1; // 初始化for (int i = 2; i <= n; i++) {dp[i] = dp[i-1] + dp[i-2]; // 转移方程}return dp[n];
}
四、蓝桥杯DP高频题型 (完整代码示例)
1. 背包问题(01背包)
// 物品重量w[], 价值v[], 背包容量W
int knapsack(int[] w, int[] v, int W) {int n = w.length;int[][] dp = new int[n+1][W+1];for (int i = 1; i <= n; i++) {for (int j = 0; j <= W; j++) {if (j < w[i-1]) dp[i][j] = dp[i-1][j];elsedp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-w[i-1]] + v[i-1]);}}return dp[n][W];
}
2. 最长公共子序列(LCS)
int lcs(String s1, String s2) {int m = s1.length(), n = s2.length();int[][] dp = new int[m+1][n+1];for (int i = 1; i <= m; i++) {for (int j = 1; j <= n; j++) {if (s1.charAt(i-1) == s2.charAt(j-1))dp[i][j] = dp[i-1][j-1] + 1;elsedp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);}}return dp[m][n];
}
五、DP优化技巧(空间压缩)
很多DP问题可以将二维数组优化为一维,例如:
int climbStairsOpt(int n) {if (n <= 2) return n;int pre1 = 1, pre2 = 1; // 只需要记录前两个状态for (int i = 2; i <= n; i++) {int curr = pre1 + pre2;pre2 = pre1;pre1 = curr;}return pre1;
}
六、训练建议(来自蓝桥杯冠军)
- 刻意练习路线:
-
- 阶段1:斐波那契→爬楼梯→打家劫舍
- 阶段2:背包问题系列(01/完全/多重背包)
- 阶段3:字符串DP(LCS/编辑距离)
- 阶段4:树形DP/状态压缩DP[2]
- DEBUG技巧:
-
- 打印dp表观察状态变化
- 先写暴力递归再改DP
- 使用注释明确每个状态定义
结语:DP思想的应用
动态规划思想不仅用于算法竞赛,在实际开发中也有广泛应用:
- 文本差异比较(Git的diff)
- 路由优化(最短路径)
- 资源调度(优化分配)
互动:你遇到过哪些DP难题?欢迎在评论区讨论
相关文章:
深入浅出动态规划:从基础到蓝桥杯实战(Java版)
引言:为什么你需要掌握动态规划? 动态规划(DP)是算法竞赛和面试中的常客,不仅能大幅提升解题效率(时间复杂度通常为O(n)或O(n))[4],更是解决复杂优化问题的利器。统计显示ÿ…...
VS Code-i18n Ally国际化插件
前言 本文借鉴:i18n Ally 插件帮你轻松搞定国际化需求-按模块划分i18n Ally 是一款 VS Code 插件,它能通过可视 - 掘金本来是没有准备将I18n Ally插件单独写一个博客的,但是了解过后,功能强大,使用方便,解决…...
YOLO中mode.predict()参数详解
Inference arguments: ArgumentTypeDefaultDescriptionsourcestr‘ultralytics/assets’指定推理的数据源。可以是图像路径、视频文件、目录、URL 或实时源的设备 ID。支持多种格式和数据源,可在不同类型的输入中灵活应用。conffloat0.25设置检测的最小置信度阈值。…...
收敛算法有多少?
收敛算法是指在迭代计算过程中,能够使序列或函数逐渐逼近某个极限值或最优解的算法。常见的收敛算法有以下几种: 梯度下降法(Gradient Descent) 原理:通过沿着目标函数的负梯度方向更新参数,使得目标函数…...
在亚马逊云科技上使用n8n快速构建个人AI NEWS助理
前言: N8n 是一个强大的工作流自动化工具,它允许您连接不同的应用程序、服务和系统,以创建自动化工作流程,并且采用了开源MIT协议,可以放心使用,他的官方网站也提供了很多的工作流,大家有兴趣的…...
STM32单片机入门学习——第27节: [9-3] USART串口发送串口发送+接收
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.04.08 STM32开发板学习——第27节: [9-3] USART串口发送&串口发送接收 前言开发板说…...
python 3.9 随机生成 以UTF-8 编码 的随机中文
理论实践 因为python3的默认编码为UTF-8,我们将‘浪’的utf8\u6d6a进行打印测试 print(\u6d6a) >>浪 中文匹配范围有两种 [\u4e00-\u9fa5]和[\u2E80-\u9FFF],后者包括了日韩地区的汉字 由于utf采用16进制,则需要进行一个进制的变换&a…...
数字电子技术基础(四十)——使用Digital软件和Multisim软件模拟显示译码器
目录 1 使用Digital软件模拟显示译码器 1.1 原理介绍 1.2 器件选择 1.3 电路运行 1.4 结果分析 2 使用Multisim软件模拟显示译码器 2.1 器件选择 2.2 电路运行 1 使用Digital软件模拟显示译码器 1.1 原理介绍 7448常用于驱动7段显示译码器。如下所示为7448驱动BS201A…...
第十四届蓝桥杯大赛软件赛国赛C/C++研究生组
研究生C国赛软件大赛 题一:混乘数字题二:钉板上的正方形题三:整数变换题四:躲炮弹题五:最大区间 题一:混乘数字 有一点像哈希表: 首先定义两个数组,拆分ab和n 然后令n a*b 查看两个…...
innodb如何实现mvcc的
InnoDB 实现 MVCC(多版本并发控制)的机制主要依赖于 Undo Log(回滚日志)、Read View(读视图) 和 隐藏的事务字段。以下是具体实现步骤和原理: 1. 核心数据结构 InnoDB 的每一行数据(…...
多模态大语言模型arxiv论文略读(四)
A Survey on Multimodal Large Language Models ➡️ 论文标题:A Survey on Multimodal Large Language Models ➡️ 论文作者:Shukang Yin, Chaoyou Fu, Sirui Zhao, Ke Li, Xing Sun, Tong Xu, Enhong Chen ➡️ 研究机构: 中国科学技术大学、腾讯优图…...
空对象模式(Null Object Pattern)在C#中的实现详解
一 、什么是空对象模式 空对象模模是靠”空对孔象式是书丯一种引施丼文行为,行凌,凌万成,个默疤"空象象象象来飞䛿引用用用用电从延盈盈甘仙丿引用用用职从延务在仅代砷易行行 」这种燕式亲如要目的片片 也说媚平父如如 核心思烟 定义一个人 派一个 � 创建…...
在kotlin的安卓项目中使用dagger
在 Kotlin 的 Android 项目中使用 Dagger(特别是 Dagger Hilt,官方推荐的简化版)进行依赖注入(DI)可以大幅提升代码的可测试性和模块化程度。 1. 配置 Dagger Hilt 1.1 添加依赖 在 bu…...
(三)链式工作流构建——打造智能对话的强大引擎
上一篇:(二)输入输出处理——打造智能对话的灵魂 在前两个阶段,我们已经搭建了一个基础的智能对话,并深入探讨了输入输出处理的细节。今天,我们将进入智能对话的高级阶段——链式工作流构建。这一阶段的目…...
python三大库之---pandas(二)
python三大库之—pandas(二) 文章目录 python三大库之---pandas(二)六,函数6.1、常用的统计学函数6.2重置索引6.3 遍历6.3.1DataFrame 遍历6.3.2 itertuples()6.3.3 使用属性遍历 6.4 排序6.4.1 sort_index6.4.2 sort_…...
php7.4.3连接MSsql server方法
需要下载安装Microsoft Drivers for PHP for SQL Server驱动, https://download.csdn.net/download/tjsoft/90568178 实操Win2008IISphp7.4.3连接SqlServer2008数据库所有安装包资源-CSDN文库 适用于 SQL Server 的 PHP 的 Microsoft 驱动程序支持与 SQL Server …...
Flask返回文件方法详解
在 Flask 中返回文件可以通过 send_file 或 send_from_directory 方法实现。以下是详细方法和示例: 1. 使用 send_file 返回文件 这是最直接的方法,适用于返回任意路径的文件。 from flask import Flask, send_fileapp = Flask(__name__)@app.route("/download")…...
JS中的Promise对象
基本概念 Promise 是 JavaScript 中用于处理异步操作的对象。它代表一个异步操作的最终完成及其结果值。Promise 提供了一种更优雅的方式来处理异步代码,避免了传统的回调地狱。 Promise 有三种状态 Pending(等待中):初始状态&…...
macOS设置定时播放眼保健操
文章目录 1. ✅方法一:直接基于日历2. 方法二:基于脚本2.1 音乐文件获取(ncm转mp3)2.2 创建播放音乐任务2.3 脚本实现定时播放 1. ✅方法一:直接基于日历 左侧新建一个日历,不然会和其他日历混淆,看起来会有点乱 然后…...
Python 小练习系列 | Vol.14:掌握偏函数 partial,用函数更丝滑!
🧩 Python 小练习系列 | Vol.14:掌握偏函数 partial,用函数更丝滑! 本节的 Python 小练习系列我们将聚焦一个 冷门但高能 的工具 —— functools.partial。它的作用类似于“函数的预设模板”,能帮你写出更加灵活、优雅…...
记录学习的第二十三天
老样子,每日一题开胃。 我一开始还想着暴力解一下试试呢,结果不太行😂 接着两道动态规划。 这道题我本来是想用最长递增子序列来做的,不过实在是太麻烦了,实在做不下去了。 然后看了题解,发现可以倒着数。 …...
Web品质 - 重要的HTML元素
Web品质 - 重要的HTML元素 在构建一个优秀的Web页面时,HTML元素的选择和运用至关重要。这些元素不仅影响页面的结构,还直接关系到页面的可用性、可访问性和SEO表现。本文将深入探讨一些关键的HTML元素,并解释它们在提升Web品质方面的重要性。 1. <html> 根元素 HTM…...
SpringBoot整合sa-token,Redis:解决重启项目丢失登录态问题
SpringBoot整合sa-token,Redis:解决重启项目丢失登录态问题 🔥1. 痛点直击:为什么登录状态会消失?2.实现方案2.1.导入依赖2.2.新增yml配置文件 3.效果图4.结语 😀大家好!我是向阳🌞&…...
Python 字典和集合(子类化UserDict)
本章内容的大纲如下: 常见的字典方法 如何处理查找不到的键 标准库中 dict 类型的变种set 和 frozenset 类型 散列表的工作原理 散列表带来的潜在影响(什么样的数据类型可作为键、不可预知的 顺序,等等) 子类化UserDict 就创造自…...
npm fund 命令的作用
运行别人的项目遇到这个问题: npm fund 命令的作用 npm fund 是 npm 提供的命令,用于显示项目依赖中哪些包需要资金支持。这些信息来自包的 package.json 中定义的 funding 字段,目的是帮助开发者了解如何支持开源维护者。 典型场景示例 假…...
ES:账号、索引、ILM
目录 笔记1:账号权限查看、查看账号、创建账号等查看所有用户查看特定用户验证权限修改用户权限删除用户 笔记2:索引状态和内容的查看等查看所有索引查看特定索引内容查看索引映射查看索引设置查看索引统计信息查看ILM策略 笔记1:账号权限查看…...
哈希表(开散列)的实现
目录 引入 开散列的底层实现 哈希表的定义 哈希表的扩容 哈希表的插入 哈希表查找 哈希表的删除 引入 接上一篇,我们使用了闭散列的方法解决了哈希冲突,此篇文章将会使用开散列的方式解决哈希冲突,后面对unordered_set和unordered_map的…...
#在docker中启动mysql之类的容器时,没有挂载的数据...在后期怎么把数据导出外部
如果要导出 Docker 容器内的 整个目录(包含所有文件及子目录),可以使用以下几种方法: 方法 1:使用 docker cp 直接复制目录到宿主机 适用场景:容器正在运行或已停止(但未删除)。 命…...
[蓝桥杯] 挖矿(CC++双语版)
题目链接 P10904 [蓝桥杯 2024 省 C] 挖矿 - 洛谷 题目理解 我们可以将这道题中矿洞的位置理解成为一个坐标轴,以题目样例绘出坐标轴: 样例: 输入的5为矿洞数量,4为可走的步数。第二行输入是5个矿洞的坐标。输出结果为在要求步数…...
Johnson算法 流水线问题 java实现
某印刷厂有 6项加工任务J1,J2,J3,J4,J5,J6,需要在两台机器Mi和M2上完 成。 在机器Mi上各任务所需时间为5,1,8,5,3,4单位; 在机器M2上各任务所需时间为7,2,2,4,7,4单位。 即时间矩阵为: T1 {5, …...
