[Algorithm][递归][斐波那契数列模型][第N个泰波那契数][三步问题][使用最小花费爬楼][解码方法]详细讲解

news2024/12/28 18:58:19

目录

  • 1.第 N 个泰波那契数
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 2.三步问题
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 3.使用最小花费爬楼梯
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 4.解码方法
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


1.第 N 个泰波那契数

1.题目链接

  • 第 N 个泰波那契数

2.算法原理详解

  • 题目解析
    请添加图片描述

  • 思路

    • 确定状态表示 -> dp[i]的含义
      • i个泰波那契数的值
    • 推导状态转移方程
      • dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]
    • 初始化
      • dp[0] = 0, dp[1] = 1, dp[2] = 1
    • 确定填表顺序:从左向右
    • 确定返回值:dp[n]
  • 空间优化:滚动数组
    请添加图片描述


3.代码实现

// v1.0 动态规划
int tribonacci(int n) 
{
    // 边界情况处理
    if(n == 0 || n == 1) return n;

    vector<int> dp(n + 1, 0);
    dp[1] = dp[2] = 1;

    for(int i = 3; i <= n; i++)
    {
        dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
    }

    return dp[n];
}
-------------------------------------------------------------------
// v2.0 动态规划 + 滚动数组空间优化
int tribonacci(int n) 
{
    // 边界情况处理
    if(n == 0 || n == 1) return n;

    int a = 0, b = 1, c = 1, ret = 1;
    for(int i = 3; i <= n; i++)
    {
        ret = a + b + c;
        a = b, b = c, c = ret; // 滚动数组
    }

    return ret;
}

2.三步问题

1.题目链接

  • 三步问题

2.算法原理详解

  • 题目解析
    请添加图片描述

  • 思路

    • 确定状态表示 -> dp[i]的含义
      • 到达i位置时,一共有多少种方法
    • 推导状态转移方程
      • dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]
    • 初始化
      • dp[1] = 1, dp[2] = 2, dp[3] = 4
    • 确定填表顺序:从左向右
    • 确定返回值:dp[n]

3.代码实现

int waysToStep(int n) 
{
    // 边界情况处理
    if(n == 1 || n == 2) return n;
    if(n == 3) return 4;

    const int MOD = 1e9 + 7;

    vector<int> dp(n + 1, 0);
    dp[1] = 1, dp[2] = 2, dp[3] = 4;

    for(int i = 4; i <= n; i++)
    {
        dp[i] = ((dp[i - 1] + dp[i - 2]) % MOD + dp[i - 3]) % MOD;
    }

    return dp[n];
} 

3.使用最小花费爬楼梯

1.题目链接

  • 使用最小花费爬楼梯

2.算法原理详解

  • 本题给出两种思路,本质相同,只是思考的方向不同
  • 思路一
    • 确定状态表示 -> dp[i]的含义
      • i位置为结尾
      • 到达i位置时,最小花费
    • 推导状态转移方程
      • dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])
    • 初始化
      • dp[0] = dp[1] = 0
    • 确定填表顺序:从左向右
    • 确定返回值:dp[n]
  • 思路二
    • 确定状态表示 -> dp[i]的含义
      • i位置为起点
      • i位置出发,到达楼顶,此时的最小花费
    • 推导状态转移方程
      • dp[i] = cost[i] + min(dp[i + 1], dp[i + 2])
    • 初始化
      • dp[n - 1] = cost[n - 1], dp[n - 2] = cost[n - 2]
    • 确定填表顺序:从右向左
    • 确定返回值:min(dp[0], dp[1])

3.代码实现

// v1.0 以i位置为结尾
int minCostClimbingStairs(vector<int>& cost) 
{
    int n = cost.size();
    vector<int> dp(n + 1);

    for(int i = 2; i <= n; i++)
    {
        dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
    }

    return dp[n];
}
----------------------------------------------------------------------------
// v2.0 以i位置为起点
int minCostClimbingStairs(vector<int>& cost) 
{
    int n = cost.size();
    vector<int> dp(n);

    dp[n - 1] = cost[n - 1], dp[n - 2] = cost[n - 2];

    for(int i = n - 3; i >= 0; i--)
    {
        dp[i] = cost[i] + min(dp[i + 1], dp[i + 2]);
    }

    return min(dp[0], dp[1]);
}

4.解码方法

1.题目链接

  • 解码方法

2.算法原理详解

  • 思路
    • 确定状态表示 -> dp[i]的含义

      • i位置为结尾时,解码方法的总数
    • 推导状态转移方程

      • 如果条件都成立dp[i] = dp[i - 1] + dp[i - 2]
        请添加图片描述
    • 初始化

      • dp[0]:只解码一个字符
        • 1 <-- 1<=a<=9
        • 0 <-- 0
      • dp[1]:只解码两个字符
        • 0 <-- 解码不出来
        • 1 <-- 两个解码出一个
        • 2 <-- 两个解码出一个 + 一个解码出一个
    • 确定填表顺序:从左向右

    • 确定返回值:dp[n - 1]

  • 优化边界及初始化dp表多开一个"虚拟结点"
    • 相当于把原来dp[1]放到了后面填表的逻辑当中了,不用进行繁琐的初始化了
    • 注意事项
      • 虚拟节点里面的值,要保证后面填表时是正确的
      • 下标的映射关系
    • 怎样处理?
      • 此时dp[1]的初始化相当于原来的dp[0]的初始化,不用做特殊处理
      • dp[0] = 1做特殊处理
        • 因为此时的dp[2]在统一的逻辑里面,会去看dp[0]dp[1]的值
          • 如果条件都成立dp[2] = dp[0] + dp[1]
        • 此时如果dp[0] == 0,相当于dp[2]前面少了一种可能
          请添加图片描述

3.代码实现

// v1.0
int numDecodings(string s) 
{
    int n = s.size();
    vector<int> dp(n, 0);

    dp[0] = s[0] != '0';

    // 处理边界情况
    if(s.size() == 1) return dp[0];

    // 一个位置解码出来一个
    if(s[0] != '0' && s[1] != '0')
    {
        dp[1]++;
    }

    // 两个位置解码出来一个
    int tmp = (s[0] - '0') * 10 + s[1] - '0';
    if(tmp >= 10 && tmp <= 26)
    {
        dp[1]++;
    }

    // Dynamic Plan
    for(int i = 2; i < n; i++)
    {
        // 一个位置解码出来一个
        if(s[i] != '0')
        {
            dp[i] += dp[i - 1];
        }

        // 两个位置解码出来一个
        int tmp = (s[i - 1] - '0') * 10 + s[i] - '0';
        if(tmp >= 10 && tmp <= 26)
        {
            dp[i] += dp[i - 2];
        }
    }

    return dp[n - 1];
}
----------------------------------------------------------------------
// v2.0 优化
int numDecodings(string s) 
{
    int n = s.size();
    vector<int> dp(n + 1, 0);

    dp[0] = 1;
    dp[1] = s[0] != '0';

    // Dynamic Plan
    for(int i = 2; i <= n; i++)
    {
        // 一个位置解码出来一个
        if(s[i - 1] != '0')
        {
            dp[i] += dp[i - 1];
        }

        // 两个位置解码出来一个
        int tmp = (s[i - 2] - '0') * 10 + s[i - 1] - '0';
        if(tmp >= 10 && tmp <= 26)
        {
            dp[i] += dp[i - 2];
        }
    }

    return dp[n];
}

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

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

相关文章

mysql中sql语句 exists 判断子句的用法

如果子查询成立才执行父查询 exists判断子查询的使用例子&#xff1a; 张三不存在所以前面的父查询不执行 后面的子句结果存在&#xff0c;所以前面的父查询被执行 where条件所连接的嵌套子查询都是&#xff0c;条件子查询 ———————————————————————…

SSM【Spring SpringMVC Mybatis】——Mybatis(二)

如果对一些基础理论感兴趣可以看这一期&#x1f447; SSM【Spring SpringMVC Mybatis】——Mybatis 目录 1、Mybatis中参数传递问题 1.1 单个普通参数 1.2 多个普通参数 1.3 命名参数 1.4 POJO参数 1.5 Map参数 1.6 Collection|List|Array等参数 2、Mybatis参数传递【#与…

数据结构与算法学习笔记八-二叉树的顺序存储表示法和实现(C语言)

目录 前言 1.数组和结构体相关的一些知识 1.数组 2.结构体数组 3.递归遍历数组 2.二叉树的顺序存储表示法和实现 1.定义 2.初始化 3.先序遍历二叉树 4.中序遍历二叉树 5.后序遍历二叉树 6.完整代码 前言 二叉树的非递归的表示和实现。 1.数组和结构体相关的一些知…

Ps 滤镜:蒙尘与划痕

Ps菜单&#xff1a;滤镜/杂色/蒙尘与划痕 Filter/Noise/Dust & Scratch 蒙尘与划痕 Dust & Scratch滤镜可用于修复图像中的小瑕疵、尘埃或划痕&#xff0c;特别适合用于清理扫描的照片或老照片中的损伤&#xff0c;以及其他因拍摄条件不理想或相机传感器上的尘埃所造成…

网络安全防护:抵御DDoS和CC攻击

在当今数字化时代&#xff0c;网络安全已成为任何组织或个人不可忽视的重要议题。DDoS&#xff08;分布式拒绝服务&#xff09;攻击和CC&#xff08;命令与控制&#xff09;攻击作为两种最为常见的网络攻击方式&#xff0c;给网络运营者和用户带来了巨大的威胁和影响。本文将介…

Acrobat Pro DC 2023 for Mac:PDF处理的终极解决方案

Acrobat Pro DC 2023 for Mac为Mac用户提供了PDF处理的终极解决方案。它具备强大的文档处理能力&#xff0c;无论是查看、编辑还是创建PDF文件&#xff0c;都能轻松胜任。在编辑功能方面&#xff0c;Acrobat Pro DC 2023支持对文本、图像进行精准的修改和调整&#xff0c;还能添…

回溯法、全排列、子集等

回溯法 感想&#xff1a;回溯算法本质是一个循环&#xff0c;有点像while循环 一些回溯法&#xff08;递归&#xff09;的经典应用 1.全排列 2.子集 其实上面两个点&#xff0c;也是对应着高中数学里面的“排列”与“组合” 1.全排列问题 给定一个集合S{a,b,c}&#xff0…

服务的war包已经丢在tomcat中但是还是没法访问,如何排查?

问题出现的现象是我已经将 XWiki 的 WAR 包放置在 Tomcat 的 webapps目录下但仍然无法访问&#xff0c;反思之后可以从下面以下几个方面来诊断和解决问题&#xff1a; 1. 确认 Tomcat 正在运行 首先&#xff0c;确保 Tomcat 服务正在正常运行。可以使用以下命令检查 Tomcat 的…

word转pdf的java实现(documents4j)

一、多余的话 java实现word转pdf可用的jar包不多&#xff0c;很多都是收费的。最近发现com.documents4j挺好用的&#xff0c;它支持在本机转换&#xff0c;也支持远程服务转换。但它依赖于微软的office。电脑需要安装office才能转换。鉴于没在linux中使用office&#xff0c;本…

字符以及字符串函数

字符以及字符串函数 求字符串长度strlen 长度不受限制的字符串函数strcpystrcatstrcmp 长度受限制的字符串函数strncpystrncatstrncmp 字符串查找strstrstrtok 错误信息报告strerror 字符分类函数字符转换函数tolowertoupper 内存操作函数memcpymemmovememcmpmemset 这篇文章注…

【算法】Dijkstra求最短路算法

TOP提示&#xff1a;Dijkstra算法只适用于不含负权边的情况 Dijkstra算法是一个基于贪心&#xff0c;广搜和动态规划 求图中某点到其他所有点的最短路径的算法 一、步骤 首先我们先总结Dijkstra算法的完整步骤 我们需要一个dis数组存储从起点到达其他节点的最短距离&…

【小迪安全2023】第62天:服务攻防-框架安全CVE复现SpringStrutsLaravelThinkPHP

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

【影片欣赏】【指环王】【魔戒:国王归来 The Lord of the Rings: The Return of the King】

往期魔戒博客见&#xff1a; 【影片欣赏】【指环王】【魔戒&#xff1a;护戒使者 The Lord of the Rings: The Fellowship of the Ring】 【影片欣赏】【指环王】【魔戒&#xff1a;双塔奇谋 The Lord of the Rings: The Two Towers】 2004年发行&#xff0c;Special Extend…

控制情绪是交易成功的根本?大错特错

布雷特斯坦伯格&#xff08;Brett Steenbarger&#xff09;是一位在美国享有盛誉的交易心理学专家&#xff0c;他曾在华尔街的多个顶尖培训中心担任交易员的心理指导。身为心理学教授兼高级交易员的布雷特在交易心理方面要比别人了解得多。而且小编觉得做一个成功的交易员只靠交…

[c++]多态的分析

多态详细解读 多态的概念多态的构成条件 接口继承和实现继承: 多态的原理:动态绑定和静态绑定 多继承中的虚函数表 多态的概念 -通俗的来说&#xff1a;当不同的对象去完成某同一行为时&#xff0c;会产生不同的状态。 多态的构成条件 必须通过基类的指针或者引用调用虚函数1虚…

KMeans,KNN,Mean-shift算法的学习

1.KMeans算法是什么&#xff1f; 在没有标准标签的情况下&#xff0c;以空间的k个节点为中心进行聚类&#xff0c;对最靠近他们的对象进行归类。 2.KMeans公式&#xff1a; 2. 1.关键分为三个部分&#xff1a; 1.一开始会定义n个中心点&#xff0c;然后计算各数据点与中心点…

重装前端整体流程

用户管理 --汇总 -- 明细-CSDN博客 一、node 这个看环境变量 2023最新版Node.js下载安装及环境配置教程&#xff08;非常详细&#xff09;从零基础入门到精通&#xff0c;看完这一篇就够了_nodejs安装及环境配置-CSDN博客 配置到国内镜像的时候&#xff0c;去看&#xff0c;淘…

05.线程

进程有哪些缺陷&#xff1f; 1.创建的代价较高 进程是OS进行资源分配的基本单位&#xff0c;也就是说创建进程是需要分配资源的&#xff0c;所以创建代价很高 2.通信不方便 进程之间要想进行通信必须借助第三方资源&#xff08;管道、内存映射、消息队列&#xff09; 线程的优…

在线教程|二次元的福音!一键部署APISR,动漫画质飞跃升级

从守护城市安全的「火眼金睛」&#xff0c;到探索人体奥秘的医学之窗&#xff0c;再到娱乐产业的视觉盛宴&#xff0c;乃至遥望宇宙的卫星视角&#xff0c;超分辨率技术重塑着我们观察世界的新维度&#xff0c;让每一寸画面绽放前所未有的清晰与真实。 近年来&#xff0c;越来…

【C++】C++中的template模板

一、泛型编程 关于模板的出现其实是在广大程序员编程中偷懒省下来的。我举个例子你们就知道了。 下述例子是用来实现swap函数的&#xff0c;利用的方式是最基础的重载。 void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(d…