蓝桥杯 Java B 组之简单动态规划(爬楼梯、斐波那契数列)
Day 6:简单动态规划(爬楼梯、斐波那契数列)
动态规划(Dynamic Programming,简称 DP)是计算机科学中的一种算法设计思想,用来解决最优解问题,它的核心思想是将大问题分解为小问题,并通过保存计算结果避免重复计算。常见的应用场景包括:最短路径、最优子结构、背包问题等。
今天,我们将详细学习两个经典的动态规划问题:
- 爬楼梯问题
- 斐波那契数列
一、动态规划概念
动态规划适用于能够分解为子问题的问题,并且子问题的解可以保存并复用。动态规划通过状态转移方程来计算最优解。
通俗理解:动态规划就像“做笔记”——把重复计算的结果记录下来,避免重复劳动。
核心思想:将大问题拆解为小问题,通过解决小问题逐步解决大问题,并保存中间结果(称为“状态”)。
1. 状态转移方程:
- 状态转移方程是用来描述从一个状态到另一个状态的关系。
- 通过状态转移方程,可以一步步得到最终的最优解。
二、爬楼梯问题
问题描述:
假设你正在爬楼梯,楼梯有 n 阶,每次可以爬 1 阶或 2 阶。你有多少种方法可以爬到楼顶?
思路分析:
- 对于楼梯的第 n 阶,你可以从第 n-1 阶跳一步,或者从第 n-2 阶跳两步。
- 所以,到达第 n 阶的方法数等于到达第 n-1 阶和第 n-2 阶的方法数之和。
状态转移方程:
f(n)=f(n−1)+f(n−2)f(n) = f(n-1) + f(n-2)
- f(n) 表示到达第 n 阶的总方法数。
- 初始条件:
- f(0) = 1(没有阶梯时有一种“爬”的方法,就是不动)
- f(1) = 1(只有一阶时,只有一种爬法)
代码实现:
public class ClimbingStairs {public static int climbStairs(int n) {if (n == 0) return 0; // 没有楼梯的情况if (n == 1) return 1; // 只有一阶的情况int first = 1; // f(1) = 1int second = 2; // f(2) = 2int result = 0;for (int i = 3; i <= n; i++) {result = first + second; // f(n) = f(n-1) + f(n-2)first = second; // 更新 f(n-1)second = result; // 更新 f(n-2)}return result;}public static void main(String[] args) {int n = 5; // 假设楼梯有 5 阶System.out.println(climbStairs(n)); // 输出结果}}
- 解释:
- 初始化 first = 1 和 second = 2,分别表示到达第 1 阶和第 2 阶的方法数。
- 通过循环从第 3 阶开始,根据状态转移方程 f(n) = f(n-1) + f(n-2) 计算到达每一阶的方法数,最终返回到达第 n 阶的总方法数。
时间复杂度: O(n)
空间复杂度: O(1)
这个解法通过空间优化,只用常数空间来存储前两个状态,因此是最优解。
三、斐波那契数列(Fibonacci Sequence)
问题描述:
斐波那契数列是一个经典的数列,定义如下:
f(0)=0f(1)=1f(n)=f(n−1)+f(n−2),n>=2f(0) = 0 f(1) = 1 f(n) = f(n-1) + f(n-2), n >= 2
即数列的前两个数字是 0 和 1,从第三项开始,每一项是前两项之和。计算第 n 项。
思路分析:
- 斐波那契数列和爬楼梯问题是同一种类型的问题。
- 第 n 项的数值是前两项之和,符合动态规划的最优子结构。
状态转移方程:
f(n)=f(n−1)+f(n−2)f(n) = f(n-1) + f(n-2)
代码实现(递归):
public class Fibonacci {// 递归实现public static int fib(int n) {if (n == 0) return 0;if (n == 1) return 1;return fib(n - 1) + fib(n - 2); // 递归调用}public static void main(String[] args) {int n = 6; // 求斐波那契数列的第 6 项System.out.println(fib(n)); // 输出结果}}
- 解释:
- 基本的递归实现,计算第 n 项的数值。
- 递归的时间复杂度是 O(2^n),因为每个递归会产生两个子问题,计算速度较慢。
改进:动态规划实现(记忆化递归)
public class FibonacciDP {public static int fib(int n) {int[] dp = new int[n + 1];dp[0] = 0; // f(0) = 0dp[1] = 1; // f(1) = 1for (int i = 2; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2]; // 状态转移方程}return dp[n];}public static void main(String[] args) {int n = 6; // 求斐波那契数列的第 6 项System.out.println(fib(n)); // 输出结果}}
- 解释:
- 使用 动态规划 数组 dp 来存储中间结果,避免重复计算。
- 时间复杂度是 O(n),空间复杂度是 O(n)。
- 为什么使用n + 1:
- 索引从0开始:在Java中,数组的索引是从0开始的。因此,如果我们想要存储从第1项到第n项的解,我们需要一个长度为n + 1的数组,这样索引范围就是从0到n。
- 方便访问:使用n + 1的数组,我们可以直接使用dp[i]来访问第i项的解,而不需要进行额外的索引转换。
优化:空间复杂度 O(1)
public class FibonacciOptimized {public static int fib(int n) {if (n == 0) return 0;if (n == 1) return 1;int first = 0, second = 1; // f(0) = 0, f(1) = 1int result = 0;for (int i = 2; i <= n; i++) {result = first + second;first = second;second = result;}return result;}public static void main(String[] args) {int n = 6; // 求斐波那契数列的第 6 项System.out.println(fib(n)); // 输出结果}}
- 解释:
- 通过空间优化,只用两个变量 first 和 second 存储前两个斐波那契数值,减少了空间复杂度。
- 时间复杂度是 O(n),空间复杂度是 O(1)。
总结:
- 递归法: 直接递归实现,虽然简单,但由于大量重复计算,效率低。
- 动态规划(DP): 通过存储中间计算结果,避免重复计算,显著提高效率。
- 空间优化: 动态规划可以通过滚动数组技巧来优化空间复杂度。
时间复杂度: O(n)
空间复杂度: O(1)(优化后的解法)
四、常考点总结
| 知识点 | 内容 | 常见问题 |
| 状态转移方程 | 动态规划的核心是递推关系(例如:f(n) = f(n-1) + f(n-2)) | 题目能否用动态规划解决,是否存在最优子结构? |
| 爬楼梯问题 | 动态规划解法,关键是通过状态转移方程f(n) = f(n-1) + f(n-2)来计算 | 边界条件的处理,空间优化的使用 |
| **斐波那契 |
动态规划解题步骤总结
定义状态:明确dp[i]表示什么(如斐波那契数、爬楼梯方法数)。
建立状态转移方程:找到dp[i]与dp[i-1]、dp[i-2]等的关系。
初始化:设置初始值(如dp[0]、dp[1])。
确定计算顺序:通常从前往后遍历。
空间优化:用变量代替数组(如滚动数组)。
常考题型
基础DP问题:斐波那契、爬楼梯、路径计数。
变种DP问题:最小路径和、背包问题简化版。
二维DP问题:网格中的动态规划(如机器人路径)。
动态规划的两个主要特征:
重叠子问题:问题可以分解为多个子问题,这些子问题不是独立的,而是相互重叠的。
最优子结构:问题的最优解包含其子问题的最优解。
爬楼梯问题
爬楼梯问题是一个经典的动态规划问题。假设你正在爬楼梯,每次可以爬1阶或2阶,问到达第n阶楼梯有多少种不同的方法。
解题思路:
状态定义:设dp[i]表示到达第i阶楼梯的方法数。
状态转移方程:dp[i] = dp[i-1] + dp[i-2],即到达第i阶的方法数等于到达第i-1阶和第i-2阶的方法数之和。
初始条件:dp[1] = 1(到达第1阶只有1种方法),dp[2] = 2(到达第2阶有2种方法:1+1或2
相关文章:
蓝桥杯 Java B 组之简单动态规划(爬楼梯、斐波那契数列)
Day 6:简单动态规划(爬楼梯、斐波那契数列) 动态规划(Dynamic Programming,简称 DP)是计算机科学中的一种算法设计思想,用来解决最优解问题,它的核心思想是将大问题分解为小问题&am…...
Hive增量迁移方案与实操PB级
客户一共1PB数据,每天新增10T,有些表只保留3天。 需要客户提供: a.tbl_size(大小GB) a.last_mtime(最新更新时间) a.tbl_ttl(保留时间) b.last_part_dt(分区值) b.last_part_size(最新分区大小) t_day(表更新规律,t几) 因为目前…...
【练习】【双指针】力扣热题100 283. 移动零
题目 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0] 示例 2: 输入: nums [0] 输出…...
Python 依赖管理的革新——Poetry 深度解析
引言 在 Python 生态中,依赖管理一直是开发者关注的重要话题。从最初的 pip 和 virtualenv,到后来的 pipenv,Python 依赖管理工具不断进化。而近年来,Poetry 作为一款集成包管理和虚拟环境管理的新兴工具,逐渐获得了广…...
从零开始学Python爬虫:(二)使用基本库urllib(下)
一、异常处理 关于某些情况下,可能会出现异常,如果不处理它们,会发生很多错误。 而urllib库提供了error模块来处理这些异常,该模块包括以下功能: (1)URLError 该类含有一个属性reason&#x…...
电商分布式场景中如何保证数据库与缓存的一致性?实战方案与Java代码详解
文章目录 一、缓存一致性问题的本质写后读不一致:更新数据库后,缓存未及时失效并发读写竞争:多个线程同时修改同一数据缓存与数据库事务不同步:部分成功导致数据错乱 二、5大核心解决方案与代码实现方案1:延迟双删策略…...
kamailio中Core Cookbook 核心配置手册
Core Cookbook 核心配置手册 版本: Kamailio SIP 服务器 v6.0.x (稳定版) 概述 本教程收集了 Kamailio 核心导出到配置文件的功能和参数。 注意: 本页参数未按字母顺序排列。 结构 kamailio.cfg 的结构可分为三部分: 全局参数模块设置路由块 建议按此顺序排列以保持清晰…...
【嵌入式Linux应用开发基础】read函数与write函数
目录 一、read 函数 1.1. 函数原型 1.2. 参数说明 1.3. 返回值 1.4. 示例代码 二、write 函数 2.1. 函数原型 2.2. 参数说明 2.3. 返回值 2.4. 示例代码 三、关键注意事项 3.1 部分读写 3.2 错误处理 3.3 阻塞与非阻塞模式 3.4 数据持久化 3.5 线程安全 四、嵌…...
一、OpenSM 架构部署及原理详解
目录 一、OpenSM 架构与核心功能 1. InfiniBand 子网管理器(SM)的作用 2. OpenSM 的架构 二、OpenSM 部署步骤(以 Linux 为例) 1. 安装依赖与软件包 2. 配置文件 3. 启动 OpenSM 服务 4. 验证部署 5. 高可用性配置(可选) 三、OpenSM 工作原理详解 1. 拓扑发现(…...
2526考研资料分享 百度网盘
通过网盘分享的文件:01、2026【考研数学】 链接:https://pan.baidu.com/s/1PwMzp_yCYqjBqa7492mP3w?pwd98wg 提取码:98wg--来自百度网盘超级会员v3的分享 通过网盘分享的文件:01、2026【考研政治】 链接:https://pan.baidu.com/s/1PwMzp_yCYqjBqa7492…...
15.1 Process(进程)类
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 通常开发时想要获得进程是比较困难的事,必须要调用CreateToolhelpSnapshot、ProcessFirst、ProcessNext等API或者诸如 Zw…...
事件传递和监控
今天介绍一下UIApplication的函数 - (BOOL)sendAction:to:from:forEvent: - (BOOL)sendAction:to:from:forEvent: 是 UIApplication 类中的一个方法,主要用于发送事件响应链中的动作(action)。它允许应用程序从一个特定的发送者(…...
CentOS 7 企业级Redis 7部署指南
CentOS 7 企业级Redis 7部署指南 目录导航 一、环境准备 1.1 依赖管理 二、离线安装 2.1 源码编译安装2.2 目录结构规范 三、生产配置 3.1 主配置文件3.2 配置生成脚本 四、系统集成 4.1 Systemd服务文件4.2 服务管理命令 五、安全加固 5.1 网络安全配置5.2 审计配置 六、性能…...
Python创建Excel的方式——提供4中方式可供参考
目录 专栏导读库的安装代码1——pandas代码2——openpyxl代码3——xlsxwriter代码4——xlwings总结 专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️🌈 博客主页:请点击——>…...
消息中间件深度剖析:以 RabbitMQ 和 Kafka 为核心
在现代分布式系统和微服务架构的构建中,消息中间件作为一个不可或缺的组件,承担着系统间解耦、异步处理、流量削峰、数据传输等重要职能。尤其是在面临大规模并发、高可用性和可扩展性需求时,如何选择合适的消息中间件成为了开发者和架构师们…...
回文数:简单问题中的多种优化思路
回文数:简单问题中的多种优化思路 引言 回文数(Palindrome Number)是一个有趣的问题,在算法竞赛、面试、甚至一些实际应用场景中都会遇到。最直观的方式是将数字转换成字符串,然后反转比较。但仅仅满足“能解”是不够…...
大语言模型简史:从Transformer(2017)到DeepSeek-R1(2025)的进化之路
2025年初,中国推出了具有开创性且高性价比的「大型语言模型」(Large Language Model — LLM)DeepSeek-R1,引发了AI的巨大变革。本文回顾了LLM的发展历程,起点是2017年革命性的Transformer架构,该架构通过「…...
java八股文-spring
目录 1. spring基础 1.1 什么是Spring? 1.2 Spring有哪些优点? 1.3 Spring主要模块 1.4 Spring常用注解 1.5 Spring中Bean的作用域 1.6 Spring自动装配的方式 1.7 SpringBean的生命周期 1.8 多级缓存 1.9 循环依赖? 1 .8.1 原因 1.8…...
机器学习--实现多元线性回归
机器学习—实现多元线性回归 本节顺延机器学习--线性回归中的内容,进一步讨论多元函数的回归问题 y ′ h ( x ) w ⊤ ∙ x b y^{\prime}h(x)w^\top\bullet xb y′h(x)w⊤∙xb 其中, w T ⋅ x 就是 W 1 X 1 w 2 X 2 w 3 X 3 ⋯ w N X N \text{其中,}w^\math…...
vue3响应式丢失解决办法(三)
vue3的响应式的理解,与普通对象的区别(一) vue3 分析总结响应式丢失问题原因(二) 经过前面2篇文章,知道了响应式为什么丢失了,但是还是碰到了丢失情况,并且通过之前的内容还不能解…...
NLP 八股 DAY1:BERT
BERT全称:Pre-training of deep bidirectional transformers for language understanding,即深度双向Transformer。 模型训练时的两个任务是预测句⼦中被掩盖的词以及判断输⼊的两个句⼦是不是上下句。在预训练 好的BERT模型后⾯根据特定任务加上相应的⽹…...
蓝桥与力扣刷题(230 二叉搜索树中第k小的元素)
题目:给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 小的元素(从 1 开始计数)。 示例 1: 输入:root [3,1,4,null,2], k 1 输出:1示例 2ÿ…...
半遮挡检测算法 Detecting Binocular Half-Occlusions
【1. 背景】: 本文分析【Detecting Binocular Half-Occlusions:Empirical Comparisons of Five Approaches】Geoffrey Egnal和Richard P. Wildes于2002年发表在IEEE Transactions on Pattern Analysis and Machine Intelligence上,这是1篇中…...
PHP培训机构教务管理系统小程序
🔑 培训机构教务管理系统——智慧教育,高效管理新典范 🚀 这款教务管理系统,是基于前沿的ThinkPHP框架与Uniapp技术深度融合,匠心打造的培训机构管理神器。它犹如一把开启高效运营与精细管理的金钥匙,专为…...
《LeetCode 763. 划分字母区间 | 高效分割字符串》
内容: 问题描述: 给定一个字符串 S,将字符串分割成若干个子串,使得每个子串中的字符都不重复,并且返回每个子串的长度。 解题思路: 找到每个字符最后一次出现的位置:我们首先遍历一遍字符串&a…...
无人机不等同轴旋翼架构设计应用探究
“结果显示,对于不等组合,用户应将较小的螺旋桨置于上游以提高能效,但若追求最大推力,则两个相等的螺旋桨更为理想。” 在近期的研究《不等同轴旋翼性能特性探究》中,Max Miles和Stephen D. Prior博士深入探讨了不同螺…...
什么是 大语言模型中Kernel优化
什么是 大语言模型中Kernel优化 目录 什么是 大语言模型中Kernel优化Kernel优化操作系统内核优化深度学习计算内核优化手工优化原理举例Flash Attention,Faster TransformerKernel优化 大语言模型存在访存密集操作(如注意力机制、LayerNorm等),这些操作使得GPU计算性能无法…...
DeepSeek与ChatGPT:AI语言模型的全面对决
DeepSeek与ChatGPT:AI语言模型的全面对决 引言:AI 语言模型的时代浪潮一、认识 DeepSeek 与 ChatGPT(一)DeepSeek:国产新星的崛起(二)ChatGPT:AI 界的开拓者 二、DeepSeek 与 ChatGP…...
CTFHub技能树-密码口令wp
目录 引言弱口令默认口令 引言 仅开放如下关卡 弱口令 通常认为容易被别人(他们有可能对你很了解)猜测到或被破解工具破解的口令均为弱口令。 打开环境,是如下界面,尝试一些弱口令密码无果 利用burpsuite抓包,然后爆…...
Deepseek R1模型本地化部署与API实战指南:释放企业级AI生产力
摘要 本文深入解析Deepseek R1开源大模型的本地化部署流程与API集成方案,涵盖从硬件选型、Docker环境搭建到模型微调及RESTful接口封装的完整企业级解决方案。通过电商评论分析和智能客服搭建等案例,展示如何将前沿AI技术转化为实际生产力。教程支持Lin…...
