【数据结构与算法】递推法和递归法解题(递归递推算法典型例题)

news2024/12/24 11:12:29

目录

  • 【算法】递推法和递归法
    • 递推算法
      • 递推算法的特点
    • 递归算法
      • 递归算法的特点
    • 递归法与递推法的算法设计例题
      • 例题一:斐波那契数列(递归递推两种方法 以及 改进算法)
      • 例题二:数字三角形问题
      • 例题三:扑克牌42点问题

更多算法例题链接: 【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题

【算法】递推法和递归法

递推算法递归算法是两种常用的算法思想,它们在解决实际问题时常常被使用。虽然它们的名称相似,但在实现和应用上存在一些区别。

递推算法

递推法的核心在于找到递推关系式。这种方法可以将复杂的计算过程转化为简单的重复步骤,充分利用计算机在运行程序时的时间局部性和空间局部性。

递推算法的特点

递推算法解题的基本思路:

  1. 将复杂计算转换为简单重复运算;
  2. 通过找到递推关系式进行简化运算;
  3. 利用计算机的特性,减少运行时间。
  4. 递推算法的一般步骤:

根据题目确定数据项,并找到符合要求的递推关系式;

  1. 根据递推关系式设计递推程序;
  2. 根据题目找到递推的终点;
  3. 单次查询可以不进行存储,
  4. 多次查询都要进行存储;
  5. 按要求输出答案即可。

递归算法

递归算法:递归算法是一种自顶向下的算法,它通过不断地直接或间接调用自身的函数,通过每次改变变量完成多个过程的重复计算,直到到达边界之后,结束调用。(与递推法相似的是,递归与递推都是将一个复杂过程分解为几个简单重复步骤进行计算。)

递归算法的实现的核心分治策略,即分而治之,将复杂过程分解为规模较小的同类问题,通过解决若干个小问题,进而解决整个复杂问题。

递归算法的特点

递归算法设计的一般步骤:

  1. 根据题目设计递归函数中的运算部分;
  2. 根据题目找到递归公式,题目可能会隐含给出,也可能需要自己进行推导;
  3. 找到递归出口,即递归的终止条件。

递归法与递推法的算法设计例题

例题一:斐波那契数列(递归递推两种方法 以及 改进算法)

在这里插入图片描述
分析得:

  1. 递推:
    这个题给出递推式
    F ( n ) = F ( n − 1 ) + F ( n − 2 ) F(n)=F(n−1)+F(n−2) F(n)=F(n1)+F(n2)
    转化为可用的递推关系,即
    F ( n ) + F ( n + 1 ) = F ( n + 2 ) F(n)+F(n+1)=F(n+2) F(n)+F(n+1)=F(n+2)

递推代码示例:

#include <iostream>
using namespace std;

int main()
{

    int n; //第几个数
    int x=0; //F(n)
    int y=1; //F(n+1)
    int ans; //F(n+2)

    cin>>n;

    if(n==0) ans=0;
    else if(n==1) ans=1;
    else {
        for(int i=2;i<=n;i++)
        {//递推
            ans=x+y;
            x=y;
            y=ans;
        }
    }
    cout<<ans<<endl;

}

改进算法(假如:将进行M次查询,每次输入一个N,其中n小于30):
存储型的递推

//每次查询后就存储下来 方便下次的查询
#include <iostream>
using namespace std;
int F[35];

void init()
{
    F[0]=0;

    F[1]=1;

    for(int i=2;i<=30;i++)
    {
        F[i]=F[i-1]+F[i-2];
    }//运行的时候 前三十个 每个都计算了
}
int main()
{

    int m; //m次查询
    int n; //第几个数
    init();

    cin>>m;

    while(m>0){
        m-=1;
        cin>>n;
        cout<<F[n]<<endl;
    }
}
  1. 递归
    递归表达式为:
    F ( n ) = F ( n − 1 ) + F ( n − 2 ) F(n)=F(n-1)+F(n-2) F(n)=F(n1)+F(n2)
    递归出口为:
//递归出口1
    if(n==0)
        return 0;

//递归出口2
    else if(n==1 )
        return 1;

递归代码示例:


#include <iostream>
using namespace std;

int fn(int n)
{
    //递归出口1
    if(n==0)
        return 0;

    //递归出口2
    else if(n==1 )
        return 1;
    else
        return fn(n-1)+fn(n-2); //递归关系式
}


int main()
{
    int n; //第几个数
    int ans;
    cin>>n;
    ans=fn(n);
    cout<<ans<<endl;

}

改进递归(假如:将进行M次查询,每次输入一个N,其中n小于30)算法:
存储型的递归

#include <iostream>
using namespace std;
int F[35];

int fn(int n)
{
    //递归出口1
    if(n==0)
    {
        F[0]=0;
        return 0;
    }

    //递归出口2
    else if(n==1 )
    {
        F[1]=1;
        return 1;
    }

    else
    {
        F[n]=fn(n-1)+fn(n-2);
        return F[n]; //递归关系式
    }
}

int main()
{
    int m; //m次查询
    int n; //第几个数

    fn(30);//一次性 全算了一遍
    cin>>m;

    while(m>0){//然后 直接输出结果
        m-=1;
        cin>>n;
        cout<<F[n]<<endl;
    }
}

例题二:数字三角形问题

在这里插入图片描述

输入样例:

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

输出样例:

30

分析题目可得递推表达式为:
a[i][j] = max{a[i][j]+a[i+1][j],a[i][j]+a[i+1][j+1]}
题解代码示例:

#include<iostream>
using namespace std;

int main()
{
    int n; //n层
    int a[101][101]; //路径矩阵
    cin>>n;

    //输入数字三角形的值
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=i; j++)
        {

        cin>>a[i][j]; //输入原始数据

        }
    }

    //递推开始

    for (int i=n-1; i>=1; i--)//从最后一层逆推
    {
        for (int j=1; j<=i; j++)
        {

            if (a[i+1][j]>=a[i+1][j+1])
                a[i][j]+=a[i+1][j];     //路径选择

            else
                a[i][j]+=a[i+1][j+1];
        }
    }

    cout<<a[1][1]<<endl;
}

例题三:扑克牌42点问题

在这里插入图片描述
输入示例:

K A Q 6 2 3 
YES

在这里插入图片描述

在这里插入图片描述
第一步:对输入的数据进行处理

//对输入的数据 进行处理
for(int i=0;i<6;i++){
		char c;
		//scanf("%c",&c);
		cin>>c;
		if(c=='A')
			a[i]=1;
		else if(c=='J')
			a[i]=11;
		else if(c=='Q')
			a[i]=12;
		else if(c=='K')
			a[i]=13;
		else
			a[i]=(int)(c-'0');

	}

第二步:计算每种可能的结果

	ans[0].push_back(a[0]);
	for(int i=1;i<=5;i++){
		for(int j=0;j<ans[i-1].size();j++){
			ans[i].push_back(ans[i-1][j]+a[i]);
			ans[i].push_back(ans[i-1][j]-a[i]);
			ans[i].push_back(ans[i-1][j]*a[i]);
			ans[i].push_back(ans[i-1][j]/a[i]);
		}
	}

第三步:判断ans[5]中是否有42

int flag = 0;
	for(int i=0;i<ans[5].size();i++){
		if(ans[5][i]==42){
			flag=1;
			break;
		}
	}
	
	if(flag== 1)
		cout<<"YES"<<endl;
	else
		cout<<"NO"<<endl;

题解代码示例:

#include<iostream>
#include<vector>
using namespace std;

vector<int> ans[6]; //创建大一点 记录五次计算的结果
int a[6]={0}; //存放输入的六个数据

int main()
{
	for(int i=0;i<6;i++){
		char c;
		//scanf("%c",&c);
		cin>>c;
		// 根据输入字符的不同,赋予对应的值给a数组
		if(c=='A')
			a[i]=1;
		else if(c=='J')
			a[i]=11;
		else if(c=='Q')
			a[i]=12;
		else if(c=='K')
			a[i]=13;
		else
			a[i]=(int)(c-'0');

		}
	ans[0].push_back(a[0]);
	// 计算可能的运算结果
	for(int i=1;i<=5;i++){
		for(int j=0;j<ans[i-1].size();j++){
		 // 将上一步结果与a[i]进行加减乘除运算,并将结果添加到ans[i]中
			ans[i].push_back(ans[i-1][j]+a[i]);
			ans[i].push_back(ans[i-1][j]-a[i]);
			ans[i].push_back(ans[i-1][j]*a[i]);
			ans[i].push_back(ans[i-1][j]/a[i]);
		}
	}
	// 检查是否有结果等于42
	int flag = 0;
	for(int i=0;i<ans[5].size();i++){
		if(ans[5][i]==42){
			flag=1;
			break;
		}
	}
	
	if(flag== 1)
		cout<<"YES"<<endl;
	else
		cout<<"NO"<<endl;
	return 0;
 } 

感谢阅读!!!
更多算法例题链接: 【数据结构与算法】C++的STL模板(迭代器iterator、容器vector、队列queue、集合set、映射map)以及算法例题

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

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

相关文章

Redis 八种常用数据类型常用命令和应用场景

5 种基础数据类型&#xff1a;String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、Set&#xff08;集合&#xff09;、Hash&#xff08;散列&#xff09;、Zset&#xff08;有序集合&#xff09;。 3 种特殊数据类型&#xff1a;HyperLogLog&#xff0…

Jpegli 简介:Google 开源的新一代 JPEG 编码库

互联网改变了我们的生活、工作和交流方式。然而&#xff0c;当页面加载缓慢时&#xff0c;它可能会变成令人沮丧的根源。这个问题的核心在于图像的编码。 为了改进这一点&#xff0c;Google 推出了 Jpegli&#xff0c;这是一种先进的 JPEG 编码库&#xff0c;它保持了高度的向…

OpenAI曾转录100万小时视频数据,训练GPT-4

4月7日&#xff0c;纽约时报在官网发布了一篇名为《科技巨头如何挖空心思&#xff0c;为AI收集数据》的技术文章。 纽约时报表示&#xff0c;OpenAI曾在2021年几乎消耗尽了互联网有用的文本数据源。为了缓解训练数据短缺的难题&#xff0c;便开发了知名开源语音识别模型Whispe…

系统架构最佳实践 -- 智慧图书管理系统架构设计

随着数字化时代的到来&#xff0c;智慧图书管理系统在图书馆和机构中扮演着重要的角色。一个优秀的图书管理系统不仅需要满足基本的借阅管理需求&#xff0c;还需要具备高效的性能、良好的扩展性和稳定的安全性。本文将讨论智慧图书管理系统的架构设计与实现&#xff0c;以满足…

spring Cache的基本使用

一、spring Cache基本介绍&#xff08;其实是通过代理对象来进行操作的&#xff09; Spring Cache 是 Spring 框架提供的一个缓存抽象&#xff0c;它能够轻松地集成到 Spring 应用程序中&#xff0c;为方法调用的结果提供缓存支持&#xff0c;从而提高应用程序的性能和响应速度…

基于拉格朗日分布算法的电动汽车充放电调度MATLAB程序

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 程序简介 该模型主要做的是基于拉格朗日分布算法的电动汽车充放电调度模型。利用蒙特卡洛模拟法模拟出电动汽车负荷曲线&#xff0c;并求解出无序充电功率曲线和有序充电曲线&#xff0c;该模型在电动汽车个…

合并单元格的excel文件转换成json数据格式

github地址: https://github.com/CodeWang-Ay/DataProcess 类型1 需求1: 类似于数据格式: https://blog.csdn.net/qq_44072222/article/details/120884158 目标json格式 {"位置": 1, "名称": "nba球员", "国家": "美国"…

C++设计模式:原型模式(八)

1、定义与动机 定义&#xff1a;使用原型实例指定创建对象的种类&#xff0c;然后通过拷贝这些原型来创建新的对象。 动机&#xff1a; 在软件系统中&#xff0c;经常面临着“某些结构复杂的对象”的创建工作&#xff1b;由于需求的变化&#xff0c;这些对象经常面临着剧烈的变…

登录压力测试

目录 一、准备测试数据 1.1数据库存储过程添加数据 1.2导出为csv作为测试数据&#xff08;账号、密码&#xff09; 二、使用fiddler抓包查看接口 2.1.抓到相关接口信息 2.2添加线程组和http请求 2.3将前面接口需要的参数去json格式化 ​2.4填写相关信息 ​ 2.5添加http…

顺序表(C语言实现)

什么是顺序表 顺序表和数组的区别 顺序表本质就是数组 结构体初阶进阶 系统化的学习-CSDN博客 简单解释一下&#xff0c;就像大家去吃饭&#xff0c;然后左边是苍蝇馆子&#xff0c;右边是修饰过的苍蝇馆子&#xff0c;但是那个好看的苍蝇馆子一看&#xff0c;这不行啊&a…

Web前端-Ajax

Ajax 概念:Asynchronous JavaScript And XML,异步的JavaScript和XML。 作用: 1.数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据。 2.异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用的校验等等…

「44」直播间换脸,揭开神秘的面纱……

「44」换脸神器 让你瞬间秒变「明星脸」带货 DeepFace是Facebook的人脸识别系统之一&#xff0c;旨在在照片和视频中准确识别和标识人脸。它使用深度学习和神经网络技术来进行高度精确的人脸匹配和验证。 DeepFace利用了大量的训练数据和先进的人脸识别算法&#xff0c;能够…

Redis中的集群(二)

节点 集群数据结构 redisClient结构和clusterLink结构的相同和不同之处 redisClient结构和clusterLink结构都有自己的套接字描述符和输入、输出缓冲区&#xff0c;这两个结构的区别在于&#xff0c;redisClient结构中的套接字和缓冲区是用于连接客户端的&#xff0c;而clust…

使用Vivado Design Suite进行功率优化

功率优化是一个可选步骤&#xff0c;它通过使用时钟门控来优化动态功率。它既可以在Project模式下使用&#xff0c;也可以在Non-Project模式下使用&#xff0c;并且可以在逻辑优化之后或布局之后运行&#xff0c;以减少设计中的功率需求。功率优化包括Xilinx的智能时钟门控解决…

git分支-分支工作流

分支工作流 现在已经掌握了分支和合并的基础知识&#xff0c;可以或应该如何使用它们&#xff1f;在本节中&#xff0c;我们将介绍一些常见的工作流程&#xff0c;这种轻量级的分支使得这些工作流程成为可能&#xff0c;因此我们可以决定是否要将它们纳入到自己的开发周期中。…

每天五分钟深度学习:如何理解逻辑回归算法的假设函数?

本文重点 我们在机器学习专栏中已经学习了逻辑回归算法,本次课程我们将重温逻辑回归算法,该算法适用于二分类的问题,本文主要介绍逻辑回归的假设函数。我们在学习线性回归算法的时候,我们已经知道了线性回归算法的假设hθ(x)=θTX(参数θ的转置*X),但是对于逻辑回归而言…

使用wget下载Github代码文件

前言 使用wget无法直接从Github链接直接下载代码文件&#xff0c;下文介绍解决方案。 解决方案 确保要下载的代码文件是公开文件&#xff0c;否则无法通过wget下载。 进入Github并找到要下载的代码文件&#xff0c;例如&#xff1a; 进入文件后&#xff0c;点击文件右侧的…

Windows完全卸载MySQL后再下载安装(附安装包)

目录 友情提醒第一章&#xff1a;如何完全卸载干净mysql教程&#xff08;三个步骤完全卸载&#xff09;1&#xff09;步骤一&#xff1a;卸载程序2&#xff09;步骤二&#xff1a;删除文件3&#xff09;步骤三&#xff1a;删除注册表信息 第二章&#xff1a;下载软件两种方式1&…

R语言数据可视化:ggplot2绘图系统

ggpolt2绘图系统被称为R语言中最高大上的绘图系统&#xff0c;使用ggplot2绘图系统绘图就像是在使用语法创造句子一样&#xff0c;把数据映射到几何客体的美学属性上。因此使用ggplot2绘图系统的核心函数ggplot来绘图必须具备三个条件&#xff0c;数据data&#xff0c;美学属性…

视频插针调研

视频插针 1、评估指标2、准确度3、实时4、视频流处理3、实时RIFE视频插帧测试 1、评估指标 参考&#xff1a;https://blog.csdn.net/weixin_43478836/article/details/104159648 https://blog.csdn.net/weixin_43605641/article/details/118088814 PSNR和SSIM PSNR数值越大表…