概念:
递推算法,又称为迭代算法,它的基本思想是将问题分解成一系列相似的子问题,通过解决较简单的子问题,逐步求解原问题。它通常用于数列、结构的构建、路径的发现等场景。在实现递推算法时,我们首先需要定义初始状态,即最基本的、不依赖于其他部分的部分。然后,我们确定递推关系,即当前状态如何由前一或多个状态推导得来。最后,要考虑算法的终止条件,即在什么情况下停止递推。
例如,斐波那契数列中每一项的值是前两项之和,这就是一个典型的递推关系。在编程中,我们可以从第三项开始,迭代计算后续每一项的值,直到达到我们想要的序列长度。通过递推,我们可以有效解决问题,并减少不必要的计算,从而提高算法效率。在讨论递推算法时,我们还会接触到递推和递归的区别,递归通常有函数自我调用的特点,而递推则更多依赖于迭代过程。
1、兔子繁殖-2410
题目描述的是经典的斐波那契数列问题,它模拟了兔子繁殖的过程。在这个问题中,每一对成年兔子每个月都会生出一对小兔子,而每对新生的小兔子在出生后两个月成熟并开始繁殖。
代码的主要逻辑是用数组 a[]
来记录每个月的兔子对数。数组的初始值 a[1]
和 a[2]
都是1,因为题目中提到开始时有一对新生的兔子,且它们在第二个月成熟。从第三个月开始,每个月的兔子对数等于前两个月兔子对数之和,即 a[i] = a[i-1] + a[i-2]
。这是因为现存的所有兔子对数(a[i-1]
)加上两个月前成熟的兔子对数(a[i-2]
,因为它们现在可以繁殖)就是当前月的总兔子对数。
最终,程序输出第 n
个月的兔子对数,即 a[n]
。由于这个数列以指数方式增长,即便 n
的值不大,兔子的数量也会变得很大。这个问题实际上是斐波那契数列问题的一个应用示例。
#include<iostream>
using namespace std;
int main(){
int n,a[50]={
};
cin>>n;
a[1]=1;//第1个月一对小兔子
a[2]=1;//第2个月一对大兔子
for(int i=3;i<=n;i++){
a[i]=a[i-2]+a[i-1];//递推关系式
}
cout<<a[n];
return 0;
}
2、台阶问题-2854
题目描述的是一个经典的递归问题,通常被称为“爬楼梯问题”。在这个问题中,每次可以爬一个或两个台阶,要计算爬到第 n
个台阶有多少种不同的方法。
代码的逻辑是使用一个数组 a[]
来存储到达每个台阶的方法数。给出的初始条件是 a[1]=1
和 a[2]=2
,即到达第一个台阶有一种方法(一步一台阶),到达第二个台阶有两种方法(一步一台阶再一步,或者一步两台阶)。
对于 n
个台阶,代码通过递推关系 a[i] = a[i-1] + a[i-2]
来计算,这表示到达第 i
个台阶的方法数等于到达前一个台阶的方法数加上到达前两个台阶的方法数。这是因为到达第 i
个台阶可以从第 i-1
个台阶迈一步到达,也可以从第 i-2
个台阶迈两步到达。
最后,程序输出到达第 n
个台阶的方法总数,即 a[n]
。这个递推关系实际上是斐波那契数列的一个变种,因为每一项都是前两项的和。
#include<iostream>
using namespace std;
int main(){
int a[21]={
},n;//n:n个台阶
a[1]=1;a[2]=2;//1个台阶1种方法 2个台阶2种方法
cin>>n;
for(int i=3;i<=n;i++){
//第3个台阶到第n个台阶
a[i]=a[i-1]+a[i-2];//递推关系式 推导每个台阶有多少种方法
}
cout<<a[n];//输出n个台阶的总方法数
return 0;
}
3、知识方格-2874
题目要求我们计算小鹿通过“知识方格路”达到目的地的不同走法数量。这个问题可以通过动态规划来解决。具体来说,我们使用一个数组 a[]
来记录到达每个方格的走法数量。初始化条件是 a[1] = 1
(一次走一个方格)和 a[2] = 2
(一次走一个方格或者一次走两个方格)。
对于每个大于2的方格位置 n
,小鹿可以从位置 n-1
走一步到达,也可以从位置 n-2
走两步到达。因此,到达位置 n
的走法数是到达位置 n-1
和 n-2
的走法数之和。这个关系可以表示为:a[n] = a[n-1] + a[n-2]
。
代码中,我们首先读入方格数 n
,然后通过一个循环计算从 3
到 n