算法中的递推算法

news2024/11/27 11:35:49

递推算法

给定一个数的序列H0,H1,…,Hn,…若存在整数n0,使当n>n0时,可以用等号(或大于号、小于号)将Hn与其前面的某些项Hi(0<i<n)联系起来,这样的式子就叫做递推关系。

递推算法是一种简单的算法,即通过已知条件,利用特定关系得出中间推论,直至得到结果的算法。 递推算法分为顺推和逆推两种。

相对于递归算法,递推算法免除了数据进出栈的过程,也就是说,不需要函数不断的向边界值靠拢,而直接从边界出发,直到求出函数值. 比如阶乘函数:f(n)=n*f(n-1) 在f(3)的运算过程中,递归的数据流动过程如下: f(3){f(i)=f(i-1)*i}-->f(2)-->f(1)-->f(0){f(0)=1}-->f(1)-->f(2)--f(3){f(3)=6} 而递推如下: f(0)-->f(1)-->f(2)-->f(3) 由此可见,递推的效率要高一些,在可能的情况下应尽量使用递推.但是递归作为比较基础的算法,它的作用不能忽视.所以,在把握这两种算法的时候应该特别注意。

顺推法

所谓顺推法是从已知条件出发,逐步推算出要解决的问题的方法叫顺推。 如斐波拉契数列,设它的函数为f(n),已知f(1)=1,f(2)=1;f(n)=f(n-2)+f(n-1)(n>=3,n∈N)。则我们通过顺推可以知道,f(3)=f(1)+f(2)=2,f(4)=f(2)+f(3)=3……直至我们要求的解。

逆推法

所谓逆推法从已知问题的结果出发,用迭代表达式逐步推算出问题的开始的条件,即顺推法的逆过程,称为逆推。

递推算法的经典例子

【案例】从原点出发,一步只能向右走、向上走或向左走。恰好走N步且不经过已走的点共有多少种走法?

样例输入:N=2

样例输出:result=7

样例输入:N=3

样例输出:result=17

解题思路:要解决走N步共有多少种走法,我们在拿到题目的时候最直接的想法就是先画出当N=1、N=2、N=3。。。。。N=n时对应走法的图例,由简单到复杂、由特殊到一般的推理过程,找出规律获得解题的思路。在数学上,我们称为归纳法。如果用编程的方法来求解这样的推理题,我们把这样的求解思路(算法)称之为递推法。递推的精髓在于f(n)的结果一般由f(n-1)、f(n-2)…..f(n-k)的前k次结果推导出来。我们在解决这类递推问题时,难点就是如何从简单而特殊的案例,找到问题的一般规律,写出f(n)与f(n-1)、f(n-2)…..f(n-k)之间的关系表达式,从而得出求解的结果。在历年noip的复赛当中,参赛选手对于这类题目都有这样的感受,往往花费了大量的时间来分析题目的一般规律,写出f(n)的一般表达式,而编程实现可能只需要几分钟的时间。所以我们在平时训练的时候,对于这样的递推题目,就必须掌握如何分析问题,从特殊推导出一般的规律,写出想要的关系表达式,问题就迎刃而解了。下面是这道题解题的心得,供大家参考:

(1)当N=1时,绘出走法图

(图1)共有3种不同的走法,也就是黑色线条的数量,即f(1)=3

(2)当N=2时,绘出走法图

(图2)共有7种不同的走法,也就是绿色线条的数量,即f(2)=7

(3)当N=3时,绘出走法图

(图3)共有17种不同的走法,也就是红色线条的数量,即f(3)=17

由此,我们不难看出,对于任何一个起点,最多可以走出3种走法,但最少必须走出2种走法。那么我们要求出f(n),实际上转换为如果我们能够得到上一步即f(n-1)有多少个终点是有3种走法的,有多少个点有2种走法的,那么问题就解决了。

a. 上一步,即f(n-1)有多少个终点是有3种走法的。

       对于N=3时,f(n-1)=f(2), 有3个点A、B、C可以走出3种不同走法的,这3个点是怎么得到的呢?它的存在与N值有没有必然的联系?如果我们能找到它与N之间的关系,问题也就解决了。有了这样的思路以后,我们不难找到这样的规律:如果f(n-2)存在,即上上步存在,那么从上上步出发的线路里面必然会有一条向上走的线路,而这条向上走的线路在到达f(n-1)之后,  向f(n)出发时也必然有左、上、右这三种走法,那么我们就得出了这样的结论:当f(n-2)存在时,f(n-2)的值实际上就等价于f(n-1)有多少个终点是有3种走法。

         b.    f(n-1)有多少个终点是有2种走法的

对于N=3时,有4个点D、E、F、G可以走出2种不同走法的,这4个点又是怎么得到的呢?它与N值有什么联系呢? 实际上我们在解决了上一个问题的时候,这个问题就变得相当容易了, f(n-1)减掉刚才有3种走法的点,剩下的点不就是只有2种走法了吗?即f(n-1)-f(n-2)。

    c. 得出f(n)的一般关系式

f(n)=3*f(n-2)+2*(f(n-1)-f(n-2) ) (n>=3)

化简:

f(n)=2*f(n-1)+f(n-2) (n>=3)

      有一点需要补充的就是,任何递推题,都会有临界条件。当N=1时,f(n)=3;,当N=2时,f(n)=7,这些都可以看成是临界条件。只有当N>=3时,即上上步存在的情况下,就可以得出f(n)的一般通式:f(n)=2*f(n-1)+f(n-2)

          (本题还有其他的解法,同学们可以继续挖掘!)

【参考程序】

#include <stdio.h>   
#include <windows.h>    
int main()    
{    
   int n;    
   int i;    
   int fn_1,fn_2;    
   printf("please input n=");    
   scanf("%d",&n); //输入任意n值    
   int fn=0;    
   if(n==1)    
     fn=3; //初始化当n=1和n=2时的临界条件    
   else if(n==2)    
     fn=7;    
   else{    
     fn_1=7;    
     fn_2=3;    
     for(i=3;i<=n;i++)    
     {    
        fn=2*fn_1+fn_2; //当n>=3时fn的通式    
        fn_2=fn_1;//更新fn_1和fn_2的值    
        fn_1=fn;    
     }    
   }    
   printf("一共有%d种走法!\n",fn);  //输出结果    
   return 0;    
}

复制

java递归算法分析

递归算法分析:就是把复杂的问题分解为若干个相对简单的子问题,一直分解下去,直到子问题有答案为止,也就是说到了递推的出口。 递归算法要注意的两点:       (1) 递归就是在方法里调用自己;       (2) 在使用递归算法时,必须要有一个明确的递归结束条件,称为递归出口。 先看一个简单的例子,求从1加到5的和,代码如下:

package com.juziku;

/**
* 递归测试
* @author sunlightcs
* 2011-3-9
* http://hi.juziku.com/sunlightcs/
*/
public class RecursionTest {
    
    /**
     * 求从1加到n的和
     */
    public static int sum(int n){
        if(n == 1){
            return 1;
        }else{
            return n + sum(n-1);
        }
    }
    
    
    public static void main(String[] args) {
        System.out.println(sum(5));
    }
}

复制

先分析一下执行的流程: n=5时,执行sum(5)方法,返回的结果为:5 + sum(4) n=4时,执行sum(4)方法,返回的结果为:4 + sum(3) n=3时,执行sum(3)方法,返回的结果为:3 + sum(2) n=2时,执行sum(2)方法,返回的结果为:2 + sum(1) n=1时,执行sum(1)方法,返回的结果为:1 再向上返回,依次执行: 2+1 3+(2+1) 4+(3+2+1) 5+(4+3+2+1) = 15 思路应该是这样的: 要知道从1加到5的和,先得知道从1加到4的和,即:5+sum(4) 要知道从1加到4的和,先得知道从1加到3的和,即:4+sum(3) 要知道从1加到3的和,先得知道从1加到2的和,即:3+sum(2) 要知道从1加到2的和,先得知道从1加到1的和,即:2+sum(1) 从而很容易看出,递归的出口为1也就是sum(1)的值为1 再看一个例子,求5的阶乘,代码如下:

package com.juziku;

/**
* 递归测试
* @author sunlightcs
* 2011-3-8
* http://hi.juziku.com/sunlightcs/
*/
public class RecursionTest {

    /**
     * 求n的阶乘
     */
    public static int multiply(int n) {
        if(n == 1){
            return 1;
        }else{
            return n * multiply(n - 1);
        }
    }
    
    
    public static void main(String[] args) {
        System.out.println(multiply(5));
    }
}

复制

文章分享自:

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

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

相关文章

免费 Selenium各大浏览器驱动【谷歌chrme、火狐Firefox、IE浏览器】

aardio群 625494397 废话不多说 直接开整&#xff01; 竟然还有脸收费 服了 下载对应版本的浏览器驱动 目标网址 应用场景 Selenium库涉及到 安装selenium库 pip install selenium-i https://mirrors.aliyun.com/pypi/simple/下载对应浏览器驱动 https://registry.npmmirror.c…

The 14th Jilin Provincial Collegiate Programming Contest(暑期训练)

Attachments - The 14th Jilin Provincial Collegiate Programming Contest - Codeforces 目录 Problem A. Chord Problem B. Problem Select Problem C. String Game Problem E. Shorten the Array Problem F. Queue Problem G. Matrix Problem J. Situation Problem L. …

ESP32设备驱动-HTU31温湿度传感器驱动

HTU31温湿度传感器驱动 文章目录 HTU31温湿度传感器驱动1、HTU31介绍2、硬件准备3、软件准备4、驱动实现1、HTU31介绍 高性能 HTU31 湿度和温度组合传感器是市场上最小和最精确的湿度传感器之一。 HTU31 提供数字和模拟版本,即使在最恶劣的环境中也能提供快速响应时间、精确测…

阿里云美国服务器怎么样?

随着业务量的扩展&#xff0c;很多小伙伴的业务发展到了海外&#xff0c;那么阿里云服务器给大家提供了方便&#xff0c;那么今天我们来说一下阿里云美国服务器好不好用&#xff0c;首先阿里云在美国有两个地域供大家选择&#xff1a;美国西部1&#xff08;硅谷&#xff09;和美…

直播美颜工具和美颜SDK:从用户需求到技术实现的完整流程

随着直播行业的迅速发展&#xff0c;用户对于直播内容的质量和视觉享受有着越来越高的要求。直播美颜工具和美颜SDK作为一种技术解决方案&#xff0c;在实时视频中提供了美化和优化的功能&#xff0c;满足了用户的需求。本文将介绍直播美颜工具和美颜SDK的完整流程&#xff0c;…

STM32——GPIO配置

文章目录 一、GPIO八种模式1. 输入2. 输出3. 如何选择GPIO的模式 二、库函数GPIO配置1. 配置代码2.参数设置 一、GPIO八种模式 GPIO的输入输出是对于STM32单片机来说的。以下仅为个人粗略笔记&#xff0c;内部电路分析可参考博客https://blog.csdn.net/k666499436/article/det…

Impala3.4源码阅读笔记(二)data-cache的Lookup实现

前言 本文为笔者个人阅读Apache Impala源码时的笔记&#xff0c;仅代表我个人对代码的理解&#xff0c;个人水平有限&#xff0c;文章可能存在理解错误、遗漏或者过时之处。如果有任何错误或者有更好的见解&#xff0c;欢迎指正。 正文 本文介绍Lookup的具体流程和细节&…

基于matlab使用深度学习进行图像类别分类(附源码)

一、前言 此示例演示如何使用预训练卷积神经网络 &#xff08;CNN&#xff09; 作为特征提取器来训练图像类别分类器。 卷积神经网络 &#xff08;CNN&#xff09; 是深度学习领域的一种强大的机器学习技术。CNN使用大量不同图像进行训练。从这些大型集合中&#xff0c;CNN可…

【软考系统架构师】数据库三大模式:外模式、概念模式和内模式

目录 1 数据库的三种模式 1.1 内模式 1.2 概念模式 1.3 外模式 2 为什么要设置这些模式 2.1 物理层 2.2 概念层 2.3 用户层 1 数据库的三种模式 1.1 内模式 也称存储模式&#xff08;Storage Schema&#xff09;&#xff0c;内模式是整个数据库的最低层表示&#xff…

【macOS 系列】mac设置截屏或其他操作的默认保存位置

1、第一步、在用户/图片文件夹下&#xff0c;新建“截图”文件夹 2、第二步、打开终端&#xff0c;输入defaults write com.apple.screencapture location ~/Pictures/截图/后回车 3、第三步、操作完成后&#xff0c;再次输入killall SystemUIServer后回车 如果你在web前端开发…

对输入图像按比例压缩、居中填充

摘要&#xff1a; 图像在输入神经网络之前&#xff0c;通常需要进行尺寸压缩&#xff0c;如yolov5的输入为640x640&#xff0c;分类网络Resnet-50的输入为224x224。通常地&#xff0c;分类网络直接将输入进行resize处理&#xff0c;而对于目标检测网络&#xff0c;为了防止目标…

js封装公用from表单验证工具验证长度邮件电话身份证非空

效果 function validateRequiredFields(formId) {var form document.getElementById(formId);var elements form.elements;var valid true;for (var i 0; i < elements.length; i) {var element elements[i];if (element.hasAttribute("req")) {var value e…

Linux:YUM仓库服务

Linux的yum仓库有4种 网络yum源 本地yum源 ftpyum源 httpyum源 第一个网络yum源不用做任何设置&#xff0c;官方默认的yum仓库配置就是从公网上下载的 环境&#xff1a; 主centos 192.168.254.11 从centos 192.168.254.10 思路&#xff1a; 我们在一台主服务器上做个本地…

30.RocketMQ之消费者拉取消息源码

highlight: arduino-light 消息拉取概述 消息消费模式有两种模式&#xff1a;广播模式与集群模式。 广播模式比较简单&#xff0c;每一个消费者需要拉取订阅主题下所有队列的消息。本文重点讲解集群模式。 在集群模式下&#xff0c;同一个消费者组内有多个消息消费者&#xff0…

split()分割字符串【JavaScript】

分割字符串 在JavaScript中&#xff0c;我们可以使用split&#xff08; &#xff09;方法把一个字符串分割成一个数组&#xff0c; 这个数组存放的是原来字符串的所有字符片段。 有多少个片段&#xff0c;数组元素个数就是多少。 语法 字符串名.split&#xff08;"分割…

TypeScript——简介、开发环境搭建、基本类型、编译选项、webpack、babel、类、面向对象的特点、接口、泛型

文章目录 第一章 快速入门0、TypeScript简介1、TypeScript 开发环境搭建2、基本类型3、编译选项4、webpack5、Babel 第二章&#xff1a;面向对象1、类&#xff08;class&#xff09;2、面向对象的特点3、接口&#xff08;Interface&#xff09;4、泛型&#xff08;Generic&…

6、架构:组件与物料设计

本章节主要是物料组件的开发设计&#xff0c;之前提到了物料的结构与构成&#xff0c;但是并没有做明确的解释。作为低代码编辑器中核心的模块之一。 物料即承担了一个提供者的角色&#xff0c;通过对编辑器注入物料组件来完成页面的渲染和可视化编辑器的编排&#xff0c;最终…

服务无法注册进Eureka

相同的配置&#xff0c;在demo里能注册&#xff0c;在自己项目的无法注册&#xff0c;眼睛都快盯出老花眼了&#xff0c;还是不行&#xff0c;果然出现的问题只有在发现问题以后才觉得简单&#xff08;虽然确实是小问题&#xff0c;但是排查了一整天&#xff0c;值得记录一下&a…

IntelliJ IDEA 控制台中文乱码和错误: 非法字符: ‘\ufeff‘

一、问题描述&#xff1a; 最近在 Windows 电脑上使用 IntelliJ IDEA 运行 Java 程序时&#xff0c;发现运行报错且控制台显示乱码。如下图1&#xff1a; &#xfffd;&#xfffd;&#xfffd;&#xfffd;: &#xfffd;&#xfffd;&#xfffd;&#xfffd; GBK &#xff…

Xshell7连接Linux服务器的两种方式

文章目录 一、创建会话式连接二、直接在窗口中连接服务器 一、创建会话式连接 打开Xshell7之后&#xff0c;点击左上角的新建。 然后可以看到一下界面 在名称位置填入会话的名称&#xff0c;自己命名的&#xff0c;叫什么都可以。 主机那里需要填写服务器的ip地址&#xff0…