简单的递归和递推

简单的递归和递推

1.递归实现指数型枚举

题意:

从 1~n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。要求同一行内的数必须升序排列。

思路:

每个数有俩种情况,选中和不选中。由于要升序排列,递归可以实现,不管选与不选都是从小到大排列的。并且选与不选没有顺序之分。

代码:

#include <iostream>
#include <algorithm>

using namespace std;
const int N=20;
int st[N];
int n;

void dfs(int u)
{
    if(u>n)
    {
        for(int i=1;i<=n;i++)
        {
            if(st[i]==1)
                printf("%d ",i);
        }
        printf("\n");
        
        return ;
    }
    
     //选
    st[u]=1;
    dfs(u+1);
    st[u]=0;
    
    //不选
    st[u]=2;
    dfs(u+1);
    st[u]=0;
    
}

int main()
{
    
    cin>>n;
    dfs(1);
    
    return 0;
}

2.递归实现排列型枚举

题意:

把 1~n 这 n 个整数排成一行后随机打乱顺序,输出所有可能的次序。

要求按照从小到大的顺序输出所有方案,每行1个。

思路:

这就是一个排列问题,每一个数都要输出,只是输出的顺序问题,很显然用递归来遍历比较好。输出结果按从小到大的顺序输出,所以从1开始遍历。这里要用一个数组来记录下顺序。

代码:

#include <iostream>
#include <algorithm>

using namespace std;
const int N=10;

int path[N];
bool st[N];
 int n;
 
void dfs(int u)
{
    if(u>n)
    {
        for(int i=1;i<=n;i++)
            printf("%d ",path[i]);
            
        printf("\n");
        return ;
    }
    
    for(int i=1;i<=n;i++)
    {
        if(st[i]) continue;
        
        st[i]=true;
        path[u]=i;
        dfs(u+1);
        st[i]=false;
    }
}

int main()
{
  
    cin>>n;
    dfs(1);
    
}

3.斐波那契数列的非递归实现

题意:

以下数列0 1 1 2 3 5 8 13 21 …被称为斐波纳契数列。

这个数列从第3项开始,每一项都等于前两项之和。

输入一个整数N,请你输出这个序列的前N项。

思路:

斐波那契的递归实现太耗费时间和空间,在比赛的时候基本都不能用,所以这里要非递归来实现,可以用数组进行预处理,一次循环就能得到所有的结果。

代码:

#include <iostream>
#include <algorithm>

using namespace std;
const int N=50;

int f[N];

int main()
{
    f[1]==0;
    f[2]=1;
    for(int i=3;i<N;i++)
    {
        f[i]=f[i-1]+f[i-2];
    }
    
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        cout<<f[i]<<' ';
        
    return 0;
}

4.递归实现组合型枚举

题意:

从 1~n 这 n 个整数中随机选出 m 个,输出所有可能的选择方案。

要求:

按照从小到大的顺序输出所有方案,每行1个。

首先,同一行内的数升序排列,相邻两个数用一个空格隔开。

其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面(例如1 3 5 7排在1 3 6 8前面)。

思路:

每个数同样有俩种选择,选和不选。不过递归的时候需要加一个参数,用来记录当前选的个数,只有选了m个才输出。

代码:

#include <iostream>
#include <algorithm>

using namespace std;
const int N=25;

bool st[N];

int path[N];
int n,m;

void dfs(int u,int cnt)
{
    if(u>n && cnt<=m) return ;
    if(cnt==m+1)
    {
        for(int i=1;i<=m;i++)
            printf("%d ",path[i]);
            
        printf("\n");
        return ;
    }
    
    //选
    st[u]=true;
    path[cnt]=u;
    dfs(u+1,cnt+1);
    st[u]=false;
    
    //不选
    st[u]=true;
    dfs(u+1,cnt);
    st[u]=false;
}
int main()
{
    cin>>n>>m;
    
    dfs(1,1);
}
发布了75 篇原创文章 · 获赞 8 · 访问量 1262

猜你喜欢

转载自blog.csdn.net/qq_40905284/article/details/104883306
今日推荐