递推、迭代、递归入门

递推、迭代、递归入门

递推和递归是用计算机解决问题的两种基本方法,最能体现计算机程序解决问题的特点。两种方法并无本质区别,只不过思考问题的方向不同。递推是从小到大,递归是从大到小。打个比方:如果要建造一个10层的楼房,递推是先建好第1层,再建第2层,再建第三层,直到第10层为止。递归是这样思考的:我要建第10层,你给我一个9层的楼房,我在上面加一层就是10层了,如不没有9层的楼房,给我一个8层的,我先加一层就是9层了…,如此还是要建第一层。

递推符合人的思考习惯,一般效率较高。递归的效率一般不如递归,但递归是计算机编程的重要思想,我们解决问题不妨从递推和递归两方面都考虑。

递推使用循环,递归使用栈(隐含的循环)

迭代不断使用变量的旧值推导出新值的过程,这一点与递推是一样的,递推一般要用到数组,会占用一定的空间,但更直观;迭代反复使用变量,占用空间较少。

理解了递推和递归,编程可算是入门了。

下文从最简单问题开始,逐步过渡到较难的问题。

1、等差数列的递推和递归:输出等差数列1 3 5 7 9 的第n项。

​ 递推:第一项是1,后一项是前一项加2,递推关系是:a[n]=a[n-1]+2

#include 
using namespace std;
int a[100];
int main(){
   int n;
   cin>>n;
   a[1]=1;
   for(int i=2;i<=n;i++)   {
       a[i]=a[i-1]+2;
    }
   cout<

​ 迭代

#include 
using namespace std;
int main(){
    int n;
    cin>>n;
    int a=1;
    for(int i=2;i<=n;i++){
        a=a+2;
    }
    cout<

​ 递归:1.f(n)表示数列的第n项 2、后一项是前一项加2,递归关系是:f(n)=f(n-1)+2 3、边界条件,当n==1时,值是1。

#include 
using namespace std;
int f(int n){
    if (n==1) return 1;
    return f(n-1)+2;
}
int main(){
   cout<

2、等比数列的递推和递归:输出等比数列1 2 4 8…的第n项

​ 递推:第一项是1,后一项是前一项乘2,递推关系是:a[n]=a[n-1]*2

#include 
using namespace std;
int a[100];
int main(){
   int n;
   cin>>n;
   a[1]=1;
   for(int i=2;i<=n;i++)   {
       a[i]=a[i-1]*2;
    }
   cout<

迭代

#include 
using namespace std;
int main(){
    int n;
    cin>>n;
    int a=1;
    for(int i=2;i<=n;i++){
        a=a*2;
    }
    cout<

递归:1.f(n)表示数列的第n项

​ 2、后一项是前一项乘2,递归关系是:f(n)=f(n-1)*2

​ 3、边界条件,当n==1时,值是1。

#include 
using namespace std;
int f(int n){
    if (n==1) return 1;
    return f(n-1)*2;
}
int main(){
   cout<

3、n的阶乘$n!=1 * 2 * 3…

​ 递推:第一项是1,后一项是前一项乘n,递推关系是:a[n]=a[n-1]*n

#include 
using namespace std;
int a[100];
int main(){
   int n;
   cin>>n;
   a[1]=1;
   for(int i=2;i<=n;i++)   {
       a[i]=a[i-1]*i;
    }
   cout<

​ 迭代

#include 
using namespace std;
int main(){
    int n;
    cin>>n;
    int a=1;
    for(int i=2;i<=n;i++){
        a=a*i;
    }
    cout<

递归:1.f(n)表示1到n项的乘积

​ 2、后一项是前一项乘n,递归关系是:f(n)=f(n-1)*n

​ 3、边界条件,当n==1时,值是1。

递推、迭代、递归入门_第1张图片

#include 
using namespace std;
int f(int n){
    if (n==1) return 1;
    return f(n-1)*n;
}
int main(){
   cout<

4、辗转相除法求两数的最大公约数

递推、迭代、递归入门_第2张图片

​ 递推:

#include 
using namespace std;
int a[100];
int main(){
   int m,n;
   cin>>m,n;
   a[1]=m;
   a[2]=n;
   int t=1;
   while(a[t]%a[t+1]){
    a[t+2]=a[t]%a[t+1];
    t++;
   }
   cout<

​ 迭代:t=a%b,b的值给a,t的值给b,再进行下一次迭代

#include 
using namespace std;
int main(){
   int a,b,t;
   cin>>a>>b;
   while (a%b!=0){
    t=a%b;
    a=b;
    b=t;
   }
   cout<

递归:1、定义f(a,b)为a和b两数的最大公约数

​ 2、边界 如果a%b==0 得到最大公约数b

​ 3、如果a%b不等于0,求b和a%b的最大公约数

#include 
using namespace std;
int f(int a,int b){
    if (a%b==0) return b;
    return f(b,a%b);
}
int main(){
   int a,b;
   cin>>a>>b;
   cout<

5、上台阶1:楼梯有n(71>n>0)阶台阶,上楼时可以一步上1阶,也可以一步上2阶,编程计算共有多少种不同的走法。

​ 迭代:第1级楼梯有1中走法;第2级楼梯有2中走法,可以1步1步上去,也可以一下跨两步;第3级楼梯由第1级楼梯跨2步上来或第2级台阶跨1步上来,有1+2,3中走法,有人可能会问,第3级不可以由第1级一步一步上来吗?是的可以,1级楼梯上来1步,就到了第2级台阶,这种走法已经包含在第2级台阶的走法中了;n级台阶可以由n-1级跨2步上来或由n-2级跨一步上来,a[n]=a[n-1]+a[n-2]
​ 递推

#include 
using namespace std;
int a[100];
int main(){
   int n;
   cin>>n;
   a[1]=1;
   a[2]=2;
   for(int i=3;i<=n;i++){
    a[i]=a[i-1]+a[i-2];
   }
   cout<

​ 迭代

#include 
using namespace std;
int main(){
   int n,a,b,t;
   a=1;
   b=2;
   cin>>n;
   if(n<3) {
        cout<

​ 递归:1、定义f(n)表示到n级台阶的走法

​ 2、n级台阶可以由n-1级跨2步上来或由n-2级跨一步上来,f(n)=f(n-1)+f(n-2)

​ 3、边界:n=1 有一种方法,n=2有2种方法

#include 
using namespace std;
int f(int n){
    if (n==1) return 1;
    if (n==2) return 2;
    return f(n-1)+f(n-2);
}
int main(){
   int n;
   cin>>n;
   cout<

6、上台阶2:楼梯有n(71>n>0)阶台阶,上楼时可以一步上1阶,也可以一步上2阶,也可以一步上3阶,编程计算共有多少种不同的走法。

​ 递推,就是前一题的扩展。分析方法类似。

#include 
using namespace std;
int a[100];
int main(){
   a[1]=1;
   a[2]=2;
   a[3]=4;
   int n;
   cin>>n;
   for(int i=4;i<=n;i++){
    a[i]=a[i-1]+a[i-2]+a[i-3];
   }
    cout<

​ 迭代

#include 
using namespace std;
long long tj(int n)
{
	if (n<=2) return n;
	if (n==3) return 4;
	long long a=1,b=2,c=4;
	long t;
	for(int i=4;i<=n;i++)
	{
		t=a+b+c;//
		a=b;//b的值给a
		b=c;//c的值给b
		c=t;//t的值给c
	}
	return c;
}

int main()
{
	int x;
	while(cin>>x && x)
	{
		cout<

​ 递归

#include 
using namespace std;
int f(int n){
    if (n==1) return 1;
    if (n==2) return 2;
    if (n==3) return 4;
    return f(n-1)+f(n-2)+f(n-3);
}
int main(){
   int n;
   cin>>n;
   cout<

7、信息学奥赛一本通 1312:昆虫繁殖:科学家在热带森林中发现了一种特殊的昆虫,这种昆虫的繁殖能力很强。每对成虫过x个月产y对卵,每对卵要过两个月长成成虫。假设每个成虫不死,第一个月只有一对成虫,且卵长成成虫后的第一个月不产卵(过x个月产卵),问过z个月以后,共有成虫多少对?0≤x≤20,1≤y≤20,X≤z≤500。

​ 递推:第1个月有一对成虫,过x月后产卵,卵要两个月长成成虫,则在x+2月内只有一对成虫。以后每月的成虫数包括两不分,一部分是一起不死的成虫,另一部分是x+2月前的卵长成的成虫。递推公式是:a[n]=a[n-1]+a[n-(x-2)]

复制代码到粘帖板
#include 
using namespace std;
long c[100];
int main(){
    long long x,y,z;
    cin>>x>>y>>z;
    for(int i=1;i<=x+2;i++){
        c[i]=1;
    }
    for(int i=x+3;i<=z+1;i++){
        c[i]=c[i-1]+c[i-(x+2)]*y;
    }
    cout<

递归:1、f(n,x,y) 表示n个月后有多少对成虫,x表示成熟后x月开始产卵,y表示每次产多少对卵

​ 2、递推关系:f(n-1,x,y)+f(n-(x+2),x,y)*y

​ 3、边界条件:x+2月前只有一对成虫

#include 
using namespace std;
long long f(int n,int x,int y){
    if (n<=x+2) return 1;
    return f(n-1,x,y)+f(n-(x+2),x,y)*y;

}
int main(){
   int n,x,y;
   cin>>x>>y>>n;
   cout<

8、信息学奥赛一本通:1196踩方格:
【题目描述】
有一个方格矩阵,矩阵边界在无穷远处。我们做如下假设:

a、每走一步时,只能从当前方格移动一格,走到某个相邻的方格上;

b、走过的格子立即塌陷无法再走第二次;

c、只能向北、东、西三个方向走;

请问:如果允许在方格矩阵上走n步,共有多少种不同的方案。2种走法只要有一步不一样,即被认为是不同的方案。
递推、迭代、递归入门_第3张图片
递推、迭代、递归入门_第4张图片
递推、迭代、递归入门_第5张图片

【方法1】递推:

如果走一步,有3种;如果走2步,有7种走法;如果走三步有17种。如果上一步是向上的,可以左右上;上一步是向左的,只能上左;上一步是向右的,只能上右。设up[i]表示向上,left[i]表示向左,right[i]表示向右,则up[i]=up[i-1]+left[i-1]+right[i-1],left[i]=left[i-1]+up[i-1],right[i]=right[i-1]+up[i-1]。

#include 
using namespace std;
int l[21],r[21],u[21];
int main()
{
    int n;
    cin>>n;
    l[1]=1,r[1]=1,u[1]=1;
    for(int i=2;i<=n;i++){
        l[i]=l[i-1]+u[i-1];
        r[i]=r[i-1]+u[i-1];
        u[i]=u[i-1]+r[i-1]+l[i-1];
    }
     cout<<l[n]+r[n]+u[n];
	return 0;
}

方法2:递推

设a[i]为第走i步有几种走法,a[i]=left[i]+right[i]+up[i]=left[i-1]+up[i-1]+right[i-1]+up[i-1]+left[i-1]+up[i-1]+right[i-1]=2*(left[i-1]+up[i-1]+right[i-1)+up[i-1]=2a[i-1]+up[i-1]=2a[i-1]+(left[i-2]+right[i-2]+up[i-2])=2*a[i-1]+a[i-2]

#include 
using namespace std;
int a[21];
int main()
{
    int n;
    cin>>n;
    a[1]=3;
    a[2]=7;
    for(int i=3;i<=n;i++){
        a[i]=2*a[i-1]+a[i-2];
    }
     cout<<a[n];
	return 0;
}

方法3:递归

#include 
using namespace std;
int f(int n){
    if (n==1) return 3;
    if (n==2) return 7;
    return 2*f(n-1)+f(n-2);
}
int main()
{
    int n;
    cin>>n;
    cout<<f(n)<<endl;
	return 0;
}

你可能感兴趣的:(递推,c++,算法,数据结构)