动态规划01 三步问题[C++]

  ​​​​​​

图源:文心一言

上机题目练习整理,本篇作为动态规划的代码,因为做题入门很少找到带图的讲解(难道是因为太简单,所以没有人嘛),所以干脆自己写一份,供小伙伴们参考~🥝🥝

  • 第1版:在力扣新手村刷题的记录~🧩🧩

编辑:梅头脑🌸

审核:文心一言

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


🧵面试题 08.01. 三步问题

🧩题目

三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模1000000007。

示例1:

 输入:n = 3 
 输出:4
 说明: 有四种走法

示例2:

 输入:n = 5
 输出:13

提示:

  1. n范围在[1, 1000000]之间

🌰解题1:数组存放

📇算法思路

  • 算法思想:
    •  由于每一步我们可以选择走1步、2步或3步,并且只能向右走,因此我们可以将问题分解为更小的子问题:到达位置 i 的方式数可以通过到达位置 i-1i-2 和 i-3 的方式数来推导。这样,我们就可以使用动态规划来逐步构建到达每个位置的方式数,直到到达目标位置 n;
    • 算法的关键在于正确地定义状态(在这里是 dp[i])和状态转移方程(在这里是 dp[i] = dp[i-1] + dp[i-2] + dp[i-3],但需要注意边界条件,确保不会访问数组的负索引)。
  • 时间复杂度:O(n),n是需要到达的目标位置,使用了1个循环,遍历步数i(从1到n);
  • 空间复杂度:O(n),代码使用了一个一维数组dp来存储到达每个位置的方式数;

⌨️算法代码

#include <iostream>  
#include <vector>  
using namespace std;  const int MOD = 1000000007; // 取模的大质数  class Solution {  
public:  int waysToStep(int n) {vector<int> dp(n + 1, 0); // 一维数组,dp[i] 表示到达位置 i 的方式数  dp[0] = 1; // 初始条件,到达位置 0 的方式数为 1  for (int i = 1; i <= n; i++) {// 遍历到达位置 i 的所有可能的前一步位置  for (int j = 1; j <= 3 && i - j >= 0; j++) {dp[i] += dp[i - j] % MOD; ; // 累加从各个前一步位置到达位置 i 的方式数,并取模  }// 输出测试// cout << "dp after step " << i << ": ";// for (int k = 0; k <= i; k++) {//    cout << dp[k] << " ";// }// cout << endl;}return dp[n]; // 返回到达位置 n 的方式数  }
};
/*  
int main() {  Solution solution;  int a = solution.waysToStep(3);  cout << "Number of ways to step to position 3: " << a << endl;  return 0;  
}
*/

 作者:文心一言

📇代码解释

1:状态方程

  • 小孩走向第 i 级台阶的位置可以是:
    • 从第 i−1 阶迈 1 阶;
    • 从第 i−2 阶迈 2 阶;
    • 从第 i−3 阶迈 3 阶;
  • 那么状态方程可以是:
    • dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];代码等价的表示为:for (int j = 1; j <= 3 && i - j >= 0; j++) { dp[i] += dp[i - j] };
    • 根据题目要求,为了避免整数溢出问题,确保结果在计算机的整数表示范围内,执行取余操作,而1000000007这是一个常见的大质数,因此算式:dp[i] = (dp[i] + dp[i - j]) % MOD; 
  • 初始状态:第0个台阶有1种方式(不动);
  • i 的范围:从1走向n级台阶;

2:算法模拟 

注意,动态数组就是一种记忆的工具,它可以记录到达 i-1 、i-1、i-3的跳法,因此计算 i 时仅用 i 的前3轮的跳法相加即可;

举个栗子,例如跳到台阶3,它有4种方法到达:

  • 1次跳3级,从0级台阶跳到3级台阶;而跳到dp[0]仅1种跳法,在第2轮的dp[0]中记录,因此dp[0]→dp[3]也是唯一跳法;
  • 1次跳2级,从1级台阶跳到3级台阶;而dp[0]跳到dp[1]仅1种跳法,在第2轮的dp[1]中记录,因此dp[1]→dp[3]也是唯一跳法;
  • 1次跳1级,从2级台阶跳到3级台阶;而dp[0]跳到dp[2]有2种跳法,在第2轮的dp[2]中记录,因此dp[2]→dp[3]也是2种跳法;
  • 相加,dp[0] + dp[1] + dp[2] = 4,即为4种台阶跳法~~
轮数 / 跳法dp[0]dp[1]dp[2]dp[3]备注
初始1
第1轮111:dp[0]→dp[1]
第2轮112

1:dp[0]→dp[1]→dp[2]

2:dp[0]→dp[2]

第3轮1124

1:dp[0]→dp[1]→dp[3]

2:dp[0]→dp[1]→dp[2]→dp[3]

3:dp[0]→dp[2]→dp[3]

4:dp[0]→dp[3]

🌰解题2:变量存放

⌨️算法代码

class Solution {
public:int waysToStep(int n) {if(n<3) return n;      // 跳到台阶1有1种方法,跳到台阶2有2种方法int base=1e9+7;        // 取模质数int dp0=1,dp1=2,dp2=4; // 初始化3种状态:跳到台阶dp0有1种方式,跳到台阶dp1有2种方式,跳到台阶dp2有3种方式int temp1,temp2;       // 记录 dp[i-1],dp[i-2]while(n--!=3){         // 台阶数n不等于3时,执行循环,并且n-1temp1=dp1,temp2=dp2;             // 使用temp1和temp2保存dp1和dp2的值,因为dp1和dp2即将被更新 dp2=((dp0+dp1)%base+dp2)%base;   // 走到第n个台阶的方法数等于走到第n-1, n-2, n-3个台阶的方法数之和dp0=temp1,dp1=temp2;             // 更新dp0和dp1为上一轮的dp1和dp2  }return dp2;            // 循环结束后,dp2中存储的就是走到第n个台阶的方法数  }
};

作者:treasure_
链接:https://leetcode.cn/problems/three-steps-problem-lcci/solutions/529898/c-dong-tai-gui-hua-by-treasure_-611d/

  • 时间复杂度:O(n),n是需要到达的目标位置,使用了1个循环,遍历步数i(从1到n);
  • 空间复杂度:O(1),不同于方法一使用数组,方法二使用了3个常数存放状态,只要更新temp1、temp2、dp2、dp0,就可以实现状态方程dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]的功能;
  • 备注:
    • 算法代码1、2在思路上非常相似,只是语法的细节有些不同;
    • 算法2我已经逐行注释在了旁边,算法思路不再赘述【emm...如果真的需要再详细解说1遍,欢迎小伙伴在评论区留言】。

🔚结语

博文到此结束,写得模糊或者有误之处,欢迎小伙伴留言讨论与批评,督促博主优化内容{例如有错误、难理解、不简洁、缺功能}等,博主会顶锅前来修改~~😶‍🌫️😶‍🌫️

我是梅头脑,本片博文若有帮助,欢迎小伙伴动动可爱的小手默默给个赞支持一下,感谢点赞小伙伴对于博主的支持~~🌟🌟

同系列的博文:🌸动态规划_梅头脑_的博客-CSDN博客

同博主的博文:🌸随笔03 笔记整理-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2778808.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Blazor SSR/WASM IDS/OIDC 单点登录授权实例5 - Winform 端授权

目录: OpenID 与 OAuth2 基础知识Blazor wasm Google 登录Blazor wasm Gitee 码云登录Blazor SSR/WASM IDS/OIDC 单点登录授权实例1-建立和配置IDS身份验证服务Blazor SSR/WASM IDS/OIDC 单点登录授权实例2-登录信息组件wasmBlazor SSR/WASM IDS/OIDC 单点登录授权实例3-服务端…

js基础(1)

操作数组 数组.push() 将一个或多个元素添加到数组末尾&#xff0c;返回数组新长度 数组.unshift() 将一个或多个元素添加到数组末尾&#xff0c;返回数组新长度 数组.pop() 删除最后一个元素&#xff0c;返回该元素的值 更灵活的删除方法&#xff0c;删除指定元素 数组.spli…

01-Spring实现重试和降级机制

主要用于在模块调用中&#xff0c;出现失败、异常情况下&#xff0c;仍需要进行重复调用。并且在最终调用失败时&#xff0c;可以采用降级措施&#xff0c;返回一般结果。 1、重试机制 我们采用spring 提供的retry 插件&#xff0c;其原理采用aop机制&#xff0c;所以需要额外…

算法||实现典型数据结构的查找、添加和删除数据 并分析其时间和空间复杂度

实现典型数据结构的查找、添加和删除数据 并分析其时间和空间复杂度 线性结构&#xff1a; 数组&#xff1a;是一种线性表数据结构&#xff0c;它用一组连续的内存空间&#xff0c;来存储一组具有相同类型的数据。 查找数据 &#xff1a;随机访问 流程图 /** 查询元素下标…

【机器学习笔记】基于实例的学习

基于实例的学习 文章目录 基于实例的学习1 基本概念与最近邻方法2 K-近邻&#xff08;KNN&#xff09;3 距离加权 KNN4 基于实例/记忆的学习器5 局部加权回归5 多种回归方式对比6 懒惰学习与贪婪学习 ​ 动机&#xff1a;人们通过 记忆和行动来推理学习。 1 基本概念与最近邻方…

C++初阶之类与对象(中)——六个默认函数详细解析

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂 目录 一.前言 二.构造函数 2.1构造函数的语法和特性 2.1.1语法 2.…

C++ dfs 的状态表示(五十一)【第十一篇】

今天我们接着学习dfs&#xff08;状态表示&#xff09;。 1.抽象形式的dfs 前面用到的 DFS 算法都是比较容易想象出搜索过程的&#xff0c;接下来我们看一些不那么容易想象搜索过程的 DFS 过程&#xff0c;这些问题我们称为抽象形式的 DFS。 来回顾一下上节课遇到的一个问题&a…

java 执行方式和类加载过程

java默认属于混合执行&#xff1a; 编译和解释并存 java先进行解释执行&#xff0c;遇到多次重复的代码会把它编程成可执行文件&#xff0c;方便下次直接执行。 可以通过VM参数来修改执行方式。 类加载过程

为什么IDM下载速度很慢,IDM下载速度很慢怎么办

为什么IDM下载速度很慢&#xff0c;IDM下载速度很慢怎么办 IDM采用的是多线程下载模式。 如果说单线程下载“一个人完成一项工作”&#xff0c;那多线程下载就是“多个人完成一项工作”。它能让用户从服务器获得更高的带宽&#xff0c;从而提高资源下载速度。一般IDM会默认使用…

MySQL篇----第十九篇

系列文章目录 文章目录 系列文章目录前言一、什么是存储过程?用什么来调用?二、如何通俗地理解三个范式?三、什么是基本表?什么是视图?四、试述视图的优点?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这…

【漏洞复现】狮子鱼CMS文件上传漏洞(image_upload.php)

Nx01 产品简介 狮子鱼CMS&#xff08;Content Management System&#xff09;是一种网站管理系统&#xff0c;它旨在帮助用户更轻松地创建和管理网站。该系统拥有用户友好的界面和丰富的功能&#xff0c;包括页面管理、博客、新闻、产品展示等。通过简单直观的管理界面&#xf…

postgresql 手动清理wal日志的101个坑

新年的第一天&#xff0c;总结下去年遇到的关于WAL日志清理的101个坑&#xff0c;以及如何相对安全地进行清理。前面是关于WAL日志堆积的原因分析&#xff0c;清理相关可以直接看第三部分。 首先说明&#xff0c;手动清理wal日志是一个高风险的操作&#xff0c;尤其对于带主从的…

70.SpringMVC怎么和AJAX相互调用的?

70.SpringMVC怎么和AJAX相互调用的&#xff1f; &#xff08;1&#xff09;加入Jackson.jar&#xff08;2&#xff09;在配置文件中配置json的消息转换器.(jackson不需要该配置HttpMessageConverter&#xff09; <!‐‐它就帮我们配置了默认json映射‐‐> <mvc:anno…

前端工程化面试题 | 04.精选前端工程化高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

禁止文件外发,文件禁止外发的方法

在当今的企业环境中&#xff0c;数据安全至关重要。 什么是企业文件外发&#xff1f; 企业文件外发指的是将企业内部的电子文件发送给组织外部的人员使用。 这种行为可能带来数据安全风险&#xff0c;因为电子文件自身具有易拷贝、易扩散、易传播的特性。 如果带有核心资产或…

AS自治系统的路由协议--BGP

BGPV4 --- IPV4 --- BGPV4 --- MPBGP --- 支持多种不同的地址组 重发布替代BGP的缺陷&#xff1a; 1&#xff0c;选路不佳 2&#xff0c;ASBR的归属问题 BGP --- 无类别路径矢量协议 1&#xff0c;无类别 --- 在传递路由信息的时候携带子网掩码 2&#xff0c;路径矢量 ---…

小游戏和GUI编程(4) | 基于 SFML 的黑客帝国字符雨

小游戏和GUI编程(4) | 基于 SFML 的黑客帝国字符雨 文章目录 小游戏和GUI编程(4) | 基于 SFML 的黑客帝国字符雨1. 简介2. 规划3. 一个字符的下落3. 一个雨滴的下落4. 每个雨滴都是独一无二的5. 重构后&#xff0c; 降落多个雨滴6. 总结7. 参考 1. 简介 使用 SFML 实现黑客帝国…

股价分布统计 100元能买股票吗?

A股的股价一般是多少&#xff1f;100元能买股票吗&#xff1f;能买多少&#xff1f; 一、买入交易规则&#xff1a; 沪深主板(包括中小板)&#xff0c;股票代码以600,000,002开头&#xff0c;每次最低买100股&#xff0c;随后以100股为单位增加&#xff0c;也就是可以买100股&…

k8s-资源限制与监控 15

资源限制 上传实验所需镜像 Kubernetes采用request和limit两种限制类型来对资源进行分配。 request(资源需求)&#xff1a;即运行Pod的节点必须满足运行Pod的最基本需求才能 运行Pod。 limit(资源限额)&#xff1a;即运行Pod期间&#xff0c;可能内存使用量会增加&#xff0…

委托和事件详解

委托和事件详解 前言一、委托1.什么是委托2.委托的声明3.Action<T>委托和Func<T>委托4.委托的缺点5.委托与lambda表达式6.委托的使用&#xff08;1&#xff09;模板方法&#xff08;2&#xff09;回调方法 二、事件1.什么是事件2.事件模型的5个步骤和组成部分&…