《C++ 动态规划》第001-002题:第N个泰波拉契数,三步问题

《C++ 动态规划》第001-002题:第N个泰波拉契数,三步问题

🔥个人主页:Cx330🌸

❄️个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》《C++知识分享》

《优选算法指南-必刷经典100题》《Linux操作系统》:从入门到入魔

《Git深度解析》:版本管理实战全解

🌟心向往之行必能至


🎥Cx330🌸的简介:


目录

前言:

01.第N个泰波拉契数

算法原理(动态规划):

思路:

解法代码(C++):

博主手记(字体还请见谅哈):

02.三步问题

算法原理(动态规划):

思路:

解法代码(C++):

博主手记(字体还请见谅哈):

结尾:


前言:

聚焦算法题实战,系统讲解三大核心板块:“精准定位最优解”——优选算法,“简化逻辑表达,系统性探索与剪枝优化”——递归与回溯,“以局部最优换全局高效”——贪心算法,讲解思路与代码实现,帮助大家快速提升代码能力

01.第N个泰波拉契数

题目链接:

1137. 第 N 个泰波那契数 - 力扣(LeetCode)

题目描述:

题目示例:

算法原理(动态规划):
思路:

1. 状态表示
这道题可以【根据题目要求】直接定义出状态表示:

dp[i] 表示:第 i 个泰波拉契数的值
2. 状态转移方程
题目已经很贴心的告诉了我们:dp[i] = dp[i-1] + dp[i-2] + dp[i-3]
3. 初始化

从我们的递推公式可以看出,dp[i] 在 i=0 以及 i=1 的时候是没有办法进行推导的,因为 dp[-2] 或 dp[-1] 不是一个有效的数据。因此我们需要在填表之前,将 0,1,2 位置的值初始化。题目中已经告诉我们 dp[0] = 0,dp[1] = dp[2] =1

4. 填表顺序
毫无疑问是【从左往右】。
5. 返回值
应该返回 dp[n] 的值。

解法代码(C++):
class Solution { public: int tribonacci(int n) { // //处理边界情况 // if(n==0) return 0; // if(n==1||n==2) return 1; // //1.创建dp表 // vector<int> dp(n+1); // //2.初始化 // dp[0]=0,dp[1]=dp[2]=1; // //3.填表 // for(int i=3;i<=n;i++) // dp[i]=dp[i-3]+dp[i-2]+dp[i-1]; // //4.返回值 // return dp[n]; //空间优化 if(n==0) return 0; if(n==1||n==2) return 1; int a=0,b=1,c=1,d=0; //填表 for(int i=3;i<=n;i++) { d=a+b+c; a=b;b=c;c=d; } return d; } };

空间优化根据滚动数组来进行模拟优化

博主手记(字体还请见谅哈):

02.三步问题

题目链接:

面试题 08.01. 三步问题 - 力扣(LeetCode)

题目描述:

题目示例:

算法原理(动态规划):
思路:

1. 状态表示
这道题可以根据【经验+题目要求】直接定义出状态表示:
dp[i] 表示:到达 i 位置时,一共有多少种方法。

2. 状态转移方程
以 i 位置状态的最近的一步,来分情况讨论:
如果 dp[i] 表示小孩上第 i 阶楼梯的所有方式,那么他应等于所有上一步的方式之和:

  • 上一步上一级台阶:dp[i] += dp[i-1]
  • 上一步上两级台阶:dp[i] += dp[i-2]
  • 上一步上三级台阶:dp[i] += dp[i-3]

综上所述,dp[i] = dp[i-1] + dp[i-2] + dp[i-3]
需要注意的是,这道题目说,由于结果可能很大,需要对结果取模。

在计算的时候,三个值全部加起来再取模是不行的,大家可以自己取试试。对于这类问题,我们每计算一次(两个数相加/乘等),都需要取一次模。否则,万一发生了溢出,我们的答案就错了。

3. 初始化
从我们的递推公式可以看出,dp[i] 在 i=0,i=1 以及 i=2 的时候是没有办法进行推导的,因为 dp[-3] dp[-2]  dp[-1] 不是一个有效的数据。

因此我们需要在填表之前,将 1,2,3 位置的值初始化。
根据题意,dp[1] = 1,dp[2] = 2,dp[3] = 4

4. 填表顺序
毫无疑问是【从左往右】。
5. 返回值
应该返回 dp[n] 的值。

解法代码(C++):
class Solution { const int MOD=1e9+7; public: int waysToStep(int n) { // if(n==1||n==2) return n; // if(n==3) return 4; // //1.创建dp表 // vector<int> dp(n+1); // //2.初始化 // dp[1]=1,dp[2]=2,dp[3]=4; // //3.填表 // for(int i=4;i<=n;i++) // dp[i]=((dp[i-1]+dp[i-2])%MOD+dp[i-3])%MOD; // return dp[n]; //空间优化 if(n==1||n==2) return n; if(n==3) return 4; int a=1,b=2,c=4,d=0; //填表 for(int i=4;i<=n;i++) { d=((a+b)%MOD+c)%MOD; a=b;b=c;c=d; } return d; } };
博主手记(字体还请见谅哈):

结尾:

总结:本文分享了两个动态规划算法题的解题思路与代码实现。第一个是第N个泰波拉契数问题,通过状态转移方程dp[i]=dp[i-1]+dp[i-2]+dp[i-3]求解,并给出了空间优化方案。第二个是三步问题,分析上台阶的不同方式得出状态转移方程dp[i]=dp[i-1]+dp[i-2]+dp[i-3],强调取模运算的重要性。两题都采用从左往右填表顺序,并提供C++实现代码及空间优化版本

Read more

2025年中秋月亮只有94.91%圆?Python告诉你真相

2025年中秋月亮只有94.91%圆?Python告诉你真相

前言: 又是一年中秋节,祝大家中秋快乐!作为程序员的我们,还有谁和我一样在外奔波而不能回家,想和大家说一声辛苦啦!既然不能回家吃月饼、赏明月,那我是不是也能用代码写下属于自己的中秋记忆,为朋友们送去我们自己特殊的中秋祝福,让技术和传统节日碰撞出新的火花。 本文目录: * 一、月相计算:今晚的月亮到底有多圆 * 1. 月相可视化 * 二、月饼切分算法:公平分配的艺术 * 1. 经典切分策略 * 2. 进阶问题:不过圆心的切分 * 三、诗词生成:中秋凑诗 * 四、月球数据可视化:用数据看月亮 * 1. 先画月球表面:模拟环形山地形 * 2. 再做月相动画:看一个月月亮怎么变 * 五、中秋快乐,记得吃月饼🥮 * 写在最后 一、月相计算:今晚的月亮到底有多圆 今天是中秋节,刷朋友圈的时候突然想到一个问题:今年中秋的月亮到底有多圆?作为Python开发者,我决定用代码来算一算。顺便整理了几个和中秋相关的有趣项目,

By Ne0inhk
告别手动维护:使用 Poetry 管理 Python 项目依赖的终极指南

告别手动维护:使用 Poetry 管理 Python 项目依赖的终极指南

目录 * 告别手动维护:使用 Poetry 管理 Python 项目依赖的终极指南 * 为什么我们需要更好的 Python 依赖管理? * 快速上手:安装与初始化 Poetry * 安装 Poetry * 初始化新项目 * 核心机制:依赖解析与锁定(Lock 机制) * pyproject.toml:声明式依赖 * poetry.lock:精确的版本冻结 * 更新依赖 * 虚拟环境:无缝集成与管理 * 默认行为 * 进入虚拟环境 Shell * 配置虚拟环境位置 * 进阶实战:脚本管理与多环境配置 * 1. 管理开发依赖 * 2. 脚本(Scripts)定义 * 3. 多环境与覆盖(Overrides) * 总结:拥抱现代化的 Python 开发流 专栏导读 ❤️ 欢迎各位佬关注!

By Ne0inhk

C/C++变量命名规范:提升代码可读性的关键

C/C++变量命名规范:提升代码可读性的关键 在大型C++项目中,比如一个集成了语音合成、深度学习推理和Web交互控制的系统(如IndexTTS2),你有没有遇到过这样的场景? 翻了三四个文件才搞明白 buf 到底是输入特征还是中间缓存; 调试时发现 flag 被反复赋值却不知道它代表什么状态; 接手同事代码后看着满屏的 data, temp, value 感觉像在解谜。 这些问题背后,往往不是算法多复杂,也不是架构设计得多糟糕——而是变量命名出了问题。 良好的命名,能让代码“自解释”;而模糊或随意的命名,则会让维护成本指数级上升。尤其在C/C++这类贴近硬件、类型系统灵活的语言中,变量名几乎是开发者理解意图的唯一可靠线索。 我们不追求炫技式的编码风格,也不推崇过度缩写或个人偏好。本文聚焦工业界广泛验证的最佳实践,结合真实开发场景(包括嵌入式、高性能服务、AI框架等),系统梳理C/C++中各类变量的命名策略。 📌 说明:虽然文中会引用 IndexTTS2 项目的上下文作为示例背景,但核心内容始终围绕

By Ne0inhk

C++中获取应用程序路径的完整方法与实战技巧

本文还有配套的精品资源,点击获取 简介:在Windows平台的C++开发中,获取应用程序的路径是实现配置读取、日志写入和资源访问等功能的基础操作。本文介绍在VS2008环境下使用Windows API(如GetModuleFileName)和Boost库(如boost::filesystem)等多种方式获取可执行文件路径的技术方案,并对比其适用场景。通过实际代码示例,帮助开发者掌握兼容性好、稳定性高的路径获取方法,提升项目可靠性。 获取应用程序路径:从底层 API 到现代 C++ 路径管理的完整演进 你有没有遇到过这样的情况——程序在自己电脑上跑得好好的,一到客户机就报错“找不到配置文件”?或者更新完版本后插件全丢了,重启直接打不开?🤔 别急,这90%的可能性不是代码逻辑的问题,而是 路径处理翻车了 。尤其是在 Windows 平台上,看似简单的“获取程序安装目录”,背后却藏着一堆坑:短路径限制、工作目录陷阱、编码乱码、缓冲区溢出……稍不注意,你的应用就成了“环境依赖型软件”。 今天我们就来彻底拆解这个问题。

By Ne0inhk