1. 通用基础算法(1.1枚举算法/1.2递推算法/1.3递归算法)

article/2025/8/23 14:44:03
  1.  通用基础算法

这部分主要介绍一下8种主要的通用基础算法思想:枚举算法、递推算法、递归算法、分治算法、贪心算法、回溯算法、动态规划算法、模拟算法,附带也会拓展介绍一些其他通用基础算法思想:数值转换算法、高精度求解算法、排序算法、排列组会算法等。

    1.  枚举算法

枚举算法也叫穷举算法或者暴力算法,它的主要思想就是直接遍历所有解决问题的可能的方法,最终找到解决问题的方法。

小时候听过一个有趣的鸡兔问题,“鸡兔四十九,一百个爪子满地走,问有多少只鸡来多少只兔?”

设有i只鸡和j只兔,则由已知可得:

                          (1)

通过二元一次方程知识很容易解出:i=48,j=1。

这个问题通过枚举算法编程解决也很容易,以下是通过枚举算法解决鸡兔问题的C语言程序。

#include<stdio.h>

#define NUM 49  //鸡兔总共的只数

int main()

{

    //声明并初始化变量i,j,n ==>鸡的只数,兔的只数,问题解的标记

    int i=0,j=0,n=0;

    //循环遍历求解i,j,n

    for (i = 1; i <= NUM; i++) {

        for (j = 1; j <= NUM; j++) {

            //通过判断是否满足求解的约束条件进行求解

            if (0 == (i + j) % 49 && 0 == (2 * i + 4 * j) % 100) {

                n++;

                printf("鸡兔问题的第%d组解为:鸡有%d只,兔有%d只。\n", n, i, j);

            }

        }

    }

    printf("鸡兔问题总共有%d组解。\n", n);

    return 0;

}

以上程序编译运行后结果如下:

鸡兔问题的第1组解为:鸡有48只,兔有1只。

鸡兔问题总共有1组解。

由于鸡兔问题本质上是正整数的二元一次确定方程组问题,数学方法求解本身就很容易,通过枚举算法求解还不能显示出明显的优势。

再举一个稍微复杂一些的例子,就可以明显看出枚举算法的威力了。例如“百鸡问题”,今有鸡翁一,值钱伍;鸡母一,值钱三;鸡鶵三,值钱一。凡百钱买鸡百只,问鸡翁、母、鶵各几何?(南北朝时的数学著作《张丘建算经》下卷最后一题)

设鸡翁x,鸡母y,鸡雏z则由已知可得:

                          (2)

 通过三元一次方程知识可以解出:x=4t/3-100,y=1=200-7t/3,z=t(t=75,78,81,84)。很明显这个问题相对来说就更难解决了,因为本质上百鸡问题是正整数的三元一次不定方程组问题,不定方程组求解自然要比确实方程组求解难了!以下是通过枚举算法解决百鸡问题的C语言程序。

#define NUM 100  //鸡翁鸡母鸡雏总共的只数

int main()

{

    //声明并初始化变量x,y,z,n ==>鸡翁的只数,鸡母的只数,鸡雏的只数,问题解的标记

    int x = 0, y = 0, z = 0,n=0;

    //循环遍历求解i,j,n

    for (x = 0; x <= NUM; x++) {

        for (y = 0; y <= NUM; y++) {

            for(z=0;z<=NUM;z++){

                //通过判断是否满足求解的约束条件进行求解

                if (NUM == (x + y + z)&& NUM == (5 * x + 3 * y + z/3) && 0==z%3) {

                    n++;

                    printf("百鸡问题的第%d组解为:鸡翁有%d只,鸡母有%d只,鸡雏有%d只。\n", n, x, y,z);

                }

           

            }

        }

    }

    printf("百鸡问题总共有%d组解。\n", n);

    return 0;

}

以上程序编译运行后结果如下:

百鸡问题的第1组解为:鸡翁有0只,鸡母有25只,鸡雏有75只。

百鸡问题的第2组解为:鸡翁有4只,鸡母有18只,鸡雏有78只。

百鸡问题的第3组解为:鸡翁有8只,鸡母有11只,鸡雏有81只。

百鸡问题的第4组解为:鸡翁有12只,鸡母有4只,鸡雏有84只。

百鸡问题总共有4组解。

通过以上两个例子可以看出,枚举算法可以用于求解确定方程组问题和不定方程组问题,但是对于求解百鸡问题这种更加复杂的不定方程组问题具有更明显的优势。

    1.  递推算法

递推算法,它的主要思想就是从已知初始条件出发,通过某种递推关系,逐步得到解决问题的中间结果和最终结果。根据递推出发推导的先后顺序,递推算法可分为顺推和逆推两种。数列问题特别适合用递推算法,这里以阶乘数列通项问题和斐波那契数列通项问题为例简单介绍递推算法。

阶乘数列通项问题:已知数列{f(n)}其首项f(1)=1,任意相邻两项之间满足f(n)=n * f(n-1),求解阶乘数列第n项。以下是阶乘数列通项问题递推算法的C语言程序。

#include<stdio.h>

int main()

{

    //声明并初始化变量第n项阶乘数列f,阶乘的阶数n

    int n=0,f=1;

    //输入要求解的阶乘的阶数n

    printf("请输入要求解阶乘的阶数:");

    scanf_s("%d", &n);

    printf("\n");

    //递推求解第n项阶乘数列f

    for (int i = 1; i <= n; i++) {

        f *= i;

    }

    printf("第%d项阶乘数列f=%d\n",n, f);

    return 0;

}

以上程序编译运行后结果如下:

请输入要求解阶乘的阶数:10

第10项阶乘数列f=3628800

斐波那契数列通项问题:已知数列{f(n)}其首项f(1)=f(2)=1,任意相邻三项之间满足f(n+1)= f(n) + f(n-1),求解斐波那契数列第n项。以下是斐波那契数列问题递推算法的C语言程序。

#include<stdio.h>

int main()

{

    //声明并初始化变量第n项斐波那契数列f,斐波那契数列的阶数n

    int n = 0, f1 =1,f2 = 1,f=f1+f2;

    //输入要求解的斐波那契的阶数

    printf("请输入要求解斐波那契数列的阶数:");

    scanf_s("%d", &n);

    printf("\n");

    //递推求解第n项斐波那契数列f

    if (1 == n) {

        f = f1;

        printf("第%d项斐波那契数列f=%d\n",n, f);

    }

    else if (2 == n) {

        f = f2;

        printf("第%d项斐波那契数列f=%d\n", n, f);

    }

    else {

        for (int i = 3; i <= n; i++) {

            f1 = f2;

            f2 = f;

            f = f1 + f2;

        }

        printf("第%d项斐波那契数列f=%d\n", n, f);

    }

    return 0;

}

以上程序编译运行后结果如下:

请输入要求解斐波那契数列的阶数:10

第10项斐波那契数列f=89

    1.  递归算法

递归算法的思想类似于分形或俄罗斯套娃,通过一层层递进调用自身、直到无法继续调用自身归返从而最终解决整个问题。网上有个解释递归有趣的说法:你打开面前这扇门,看到屋里面还有一扇门。你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门,你继续打开它。若干次之后,你打开面前的门后,发现只有一间屋子,没有门了。然后,你开始原路返回,每走回一间屋子,你数一次,走到入口的时候,你可以回答出你到底用这你把钥匙打开了几扇门。难怪L. Peter Deutsch大师说:To Iterate is Human, to Recurse, Divine。正如维基百科中所说,递归算法主要解决以下三类问题:

1、数据的定义是按递归定义的。如Fibonacci函数。

2、问题解法按递归算法实现。如Hanoi问题。

3、数据的结构形式是按递归定义的。如二叉树、广义表等。

递归算法解决问题常见的除了斐波那契数列问题和汉诺塔问题,还有分割平面问题,卡塔兰数问题,斯特林数问题、杨辉三角的存取、字符串回文判断、字符串全排列、二分查找、树的深度求解等。这里以斐波那契数列问题和汉诺塔问题为例稍作展示。

斐波那契数列通项问题:已知数列{f(n)}其首项f(1)=f(2)=1,任意相邻三项之间满足f(n+1)= f(n) + f(n-1),求解斐波那契数列第n项。以下是斐波那契数列问题递归算法的C语言程序。

#include<stdio.h>

template<typename T>

T fibonacci(T n) {

    if (1 == n || 2 == n) {

        return 1;

    }

    else return fibonacci(n - 1) + fibonacci(n - 2);

}

int main()

{

    //声明并初始化变量第n项斐波那契数列f,斐波那契数列的阶数n

    unsigned long long n = 0, f =0;

    //输入要求解的斐波那契的阶数

    printf("请输入要求解斐波那契数列的阶数:");

    scanf_s("%llu", &n);

    printf("\n");

    //递推求解第n项斐波那契数列f

    f = fibonacci(n);

    printf("第%d项斐波那契数列f=%llu\n", n, f);

    return 0;

}

以上程序编译运行后结果如下:

请输入要求解斐波那契数列的阶数:10

第10项斐波那契数列f=55

相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置n个金盘。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。问至少要挪动多少次圆盘才能完成游戏?设汉诺塔数列通项为f(n):分析可知f(1)=1、f(2)=3,任意相邻两项之间满足f(n)= 2f(n-1)+1。以下是汉诺塔数列问题递归算法的C语言程序。

#include<stdio.h>

template<typename T>

T hanoi(T n) {

    if (1 == n) {

        return 1;

    }

    else{

        return 2* hanoi(n - 1) + 1;

    }

}

int main()

{

    //声明并初始化变量第n项汉诺塔数列f,汉诺塔数列的阶数n

    unsigned long long n = 0, f = 0;

    //输入要求解的汉诺塔的阶数

    printf("请输入要求解汉诺塔数列的阶数:");

    scanf_s("%llu", &n);

    printf("\n");

    //递推求解第n项汉诺塔数列f

    f = hanoi(n);

    printf("第%d项汉诺塔数列f=%llu\n", n, f);

    return 0;

}

以上程序编译运行后结果如下:

请输入要求解汉诺塔数列的阶数:64

第64项汉诺塔数列f=18446744073709551615


http://chatgpt.dhexx.cn/article/urmFtDsV.shtml

相关文章

21、python数据结构——枚举算法

枚举算法的基本思想是根据问题的本身性质&#xff0c;一一列出问题所有可能的解&#xff0c;并在逐一列举的过程中&#xff0c;检验每个可能解是否是问题的真正解。 枚举算法是通过牺牲时间换取答案的全面性&#xff0c;属于搜索策略&#xff0c;适用于那些解变量连续、值域确…

完美立方C++(枚举算法)

思路&#xff1a;不断缩小范围的去枚举。题目要求&#xff1a;b<c<d&#xff0c;所以在for循环里 a:2~N b:2~a c:b~a d:c~a #include <iostream> using namespace std; int main() {int N;int a, b, c, d;cin >> N;for (a 2; a < N;a)for (b 2; b …

003:枚举算法(习题)

枚举算法&#xff1a;又称穷举法&#xff0c;它的思想是将所有可行的方法一一列举出来&#xff0c;看哪一种方法符合题目要求。也就是数学题中的鸡兔同笼问题&#xff0c;常见题目有百钱买百鸡&#xff0c;模糊数字&#xff0c;真假硬币&#xff0c;买公园门票&#xff0c;阿凡…

枚举算法思想

枚举算法的思想 将问题的所有可能性一一列举&#xff0c;然后根据条件判断&#xff0c;保留合适的&#xff0c;舍弃不合适的。 枚举算法的基本解题思路 确定枚举对象&#xff0c;对象的取值范围&#xff0c;对象的条件。然后逐一枚举对象。 枚举算法流程图 枚举算法的优化 …

枚举算法及其优化

引言&#xff1a; 总结一下这个简单的算法~ 一、什么是枚举算法&#xff1a; 枚举算法很简单&#xff0c;就是将问题的所有可能列举出来&#xff0c;然后通过筛选&#xff0c;找出解&#xff0c;它的时间复杂度通常很大&#xff0c;在一些题目中可能会TLE&#xff0c;因此重要的…

算法之枚举

枚举 一、理解枚举类型 枚举类型是Java 5中新增特性的一部分&#xff0c;它是一种特殊的数据类型&#xff0c;之所以特殊是因为它既是一种类(class)类型却又比类类型多了些特殊的约束&#xff0c;但是这些约束的存在也造就了枚举类型的简洁性、安全性以及便捷性。下面先来看看…

【算法】枚举算法

目录 算法详述 例题 A - 火柴棒等式 B - 砝码称重 输入格式 输出格式 算法详述 枚举&#xff1a;即对可能的解集合一一列举。 枚举算法的实现往往通过使用循环&#xff08;嵌套&#xff09;就能够轻易实现&#xff0c;所以并没有什么思维难度。 解题思路&#xff1a; …

基础算法(一):枚举算法

前言 从这篇文章开始&#xff0c;小荔枝就开始学习算法和数据结构啦&#xff01;&#xff01;&#xff01;我们先来看看入门的一些基础算法&#xff0c;在这篇文章中&#xff0c;主要介绍的是枚举算法。我们重点需要了解枚举算法使用时需要确定的条件&#xff0c;荔枝会用一道题…

常用算法——枚举算法

在进行归纳推理时&#xff0c;如果逐个考察了某类事件的所有可能情况&#xff0c;因而得出一般结论&#xff0c;那么这结论是可靠的&#xff0c;这种归纳方法叫做枚举算法 一、基本概念和算法 枚举算法简称枚举法&#xff0c;也称为列举法、穷举法&#xff0c;是暴力策略的具体…

枚举算法

一、枚举法的基本思想 枚举法又称穷举法。 基本思想是根据提出的问题枚举所有可能状态&#xff0c;并用问题给定的约束条件检验哪些状态是需要的&#xff0c;哪些状态是不需要的。 能使命题成立的状态&#xff0c;即为其解。 枚举结构&#xff1a;循环判断语句。 二、枚举…

传统人工势场法---经典算法

网上代码很多&#xff0c;这个可以直接使用。 Xo[0 0];%起点位置 k50;%计算引力需要的增益系数 K0;%初始化 m15;%计算斥力的增益系数&#xff0c;都是自己设定的。 Po0.5;%障碍影响距离&#xff0c;当障碍和车的距离大于这个距离时&#xff0c;斥力为0&#xff0c;即不受该障碍…

人工势场法(APF) —— Path Planning

版权声明&#xff1a;本文为博主原创博文&#xff0c;未经允许不得转载&#xff0c;若要转载&#xff0c;请说明出处并给出博文链接 维基百科说&#xff1a;“人工势场法&#xff08;Artificial Potential Field&#xff0c; APF&#xff09;是一种将机器人的外形视为势场中的一…

基于人工势场法的移动机器人路径规划研究(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 路径规划是移动机器人领域的热点研究方向&#xff0c;人工势场法已在工业机器人路径规划中得到广泛应用&#xff0c;近年来正逐…

11(0)-AirSim+四旋翼仿真-人工势场法避障

1.基本原理 人工势场法的基本原理为&#xff0c;根据地图内障碍物、目标点等的分布&#xff0c;构造一个人工势场&#xff0c;无人机由势能较高的位置向势能较低的位置移动。就好比是一个电场&#xff0c;电场内不同位置的电势能不同&#xff0c;对带电物体产生的力也不同&…

局部路径规划中的人工势场法

人工势场法是局部路径规划的一种比较常用的方法。这种方法假设机器人在一种虚拟力场下运动。 一、简介 如图所示&#xff0c;机器人在一个二维环境下运动&#xff0c;图中指出了机器人&#xff0c;障碍和目标之间的相对位置。 这个图比较清晰的说明了人工势场法的作用&#…

matlab箭头梯度方向场,局部路径规划算法——人工势场法

人工势场法是由Khatib于1986年提出,其方法是将移动机器人所处的环境用势场来定义,通过位置信息来控制机器人的避障行驶,基本思想是构造目标位姿引力场和障碍物周围斥力场共同作用的人工势场,搜索势函数的下降方向来寻找无碰撞路径。人工势场法避障技术使得机器人的移动能很…

基于人工势场法的车辆编队轨迹规划matlab仿真验证

给出了完整的MATLAB代码仿真&#xff1b;基于人工势场法编队的基本原理&#xff1a;通过构建车辆相对目标点的引力势场和斥力势场构建车辆所处地图下的整体势场&#xff0c;设置如图所示的势场图&#xff0c; 图中圆心为我们参考的目标点&#xff0c;其可以提供引力方向&#x…

基于人工势场法的二维平面内无人机的路径规划的matlab仿真,并通过对势场法改进避免了无人机陷入极值的问题

目录 1.算法描述 2.matlab算法仿真效果 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 人工势场法原理是&#xff1a;首先构建一个人工虚拟势场&#xff0c;该势场由两部分组成&#xff0c;一部分是目标点对移动机器人产生的引力场&#xff0c;方向由机器人指向目标点&#xf…

matlab人工势场法三维演示图,运动规划入门 | 5. 白话人工势场法,从原理到Matlab实现...

如何利用人工势场进行运动规划? 1.1 引力势场(Attractive Potential Field) 人工势场这个特殊的势场并不是一个单一的场,其实它是由两个场叠加组合而成的,一个是引力场,一个是斥力场。 顾名思义引力势场是具有吸引的性质,会将机器人从起点处朝着终点处吸引,所以引力场的存…

路径规划算法3 改进的人工势场法(Matlab)

目录 传统人工势场 引力势场 斥力势场 合力势场 传统人工势场法存在的问题 改进的人工势场函数 Matlab代码实现 参考链接&#xff1a; [1]朱伟达. 基于改进型人工势场法的车辆避障路径规划研究[D]. 江苏大学, 2017. 1986年Khatib首先提出人工势场法&#xff0c;并将其应用在…