《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

【GitHub项目推荐--ZeroClaw:零开销、零妥协的Rust原生AI助手基础设施】⭐⭐⭐

简介 ZeroClaw 是一个由ZeroClaw Labs开发的开源、快速、小型且完全自主的AI助手基础设施框架,采用100% Rust编写,秉持“零开销、零妥协”的设计哲学。该项目以其惊人的资源效率著称——能够在仅10美元的硬件上运行,内存占用低于5MB,启动时间短于10毫秒,相比同类解决方案(如OpenClaw)减少99%的内存使用和98%的部署成本。ZeroClaw不仅是一个高性能的AI助手运行时,更是一个完全可插拔的架构,允许开发者“在任何地方部署,交换任何组件”。 核心价值: * 极致效率:3.4MB的独立二进制文件,<5MB内存占用,<10ms启动时间 * 成本革命:专为边缘设备和资源受限环境设计,大幅降低AI助手部署门槛 * 完全自主:内置自治引擎,支持从监督到完全自主的不同运行模式 * 架构灵活:基于trait的模块化设计,所有核心子系统均可热插拔替换 技术定位:ZeroClaw填补了高性能AI助手框架与资源受限环境之间的空白。它既不是另一个“重型”AI平台,也不是简单的脚本工具,而是一个经过精心设计、

By Ne0inhk

计算机的种类详解:从32位到64位,一文读懂不同架构的核心差异

在日常使用计算机(电脑、服务器、嵌入式设备)的过程中,我们总会听到“32位计算机”“64位计算机”“x86架构”“ARM架构”这样的说法,甚至在安装系统、软件时,还会遇到“选择32位版本还是64位版本”的问题。 很多人对这些概念一知半解,误以为“32位和64位”只是简单的性能差异,实则二者的核心区别在于CPU的寻址能力、数据处理能力,而不同架构、不同位数的计算机,适用场景也天差地别。 本文将从“核心分类维度”出发,详细拆解计算机的各类划分方式,重点讲解32位与64位计算机的差异,同时补充其他常见分类,帮你彻底理清计算机的种类与适用场景。 一、计算机的核心分类维度(先理清逻辑) 计算机的分类方式有很多,不同维度对应不同的种类,核心分类维度主要有3种: 1. 按CPU位数(数据总线/地址总线宽度)分类:这是最贴近日常使用的分类,也是本文重点,包括8位、16位、32位、64位计算机; 2.

By Ne0inhk
大话Rust的前生今世

大话Rust的前生今世

(本故事纯属戏说,如有雷同,那绝对是因为Rust太耀眼) 文章目录 * 混沌初开,天神震怒 * 十年磨一剑,霜刃未曾试 * 独门绝技,震惊武林 * 第一式:所有权系统 - 内存管理的太极拳 * 第二式:生命周期 - 变量的生死簿 * 第三式:零成本抽象 - 白嫖的性能 * 攻城略地,诸侯臣服 * WebAssembly:新世界的开拓者 * 区块链:信任的基石 * 操作系统:旧王座的挑战者 * 嵌入式:小车扛大炮 * 生态繁荣,万国来朝 * Crates.io:包罗万象的藏经阁 * 社区:最友好的极客聚集地 * 工具链:程序员的美梦成真 * 群雄逐鹿,谁与争锋 * 未来已来,星辰大海 * 修行之路,痛并快乐 * 传奇继续,代码不朽 * Rust说

By Ne0inhk