蓝桥杯 递归and递推

递归

定义:自己调用自己

int f(int n){
    ....
    f(n)
}

例如:斐波那契数列

1、2、3、5、8、13···

int f(int n)
{
    if(n==1) return 1;
    else if(n==2) return 2;
    else return f(n-2)+f(n-1);
}

AcWing 推荐题库:

92. 递归实现指数型枚举 - AcWing题库

1~n:每个数字有选择或者不选两个方案;

方案的数量就为 n*2^n,数据范围在15之内,即15*2^15,思路:递归树

#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=15;
int n;
int st[N]; //状态,记录每个位置当前的状态,0表示还没考虑,1表示选他,2表示不选他
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]=2;
    dfs(u+1);//第一个分支不选
    st[u]=0;//恢复现场
    
    st[u]=1;
    dfs(u+1);//第二个分支选
    st[u]=0;//恢复现场
}
int main()
{
    cin>>n;
    
    dfs(1);
    
    return 0;
    
}

93 递归实现组合型枚举

93. 递归实现组合型枚举 - AcWing题库

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> 

using namespace std;
const int N = 30;
int n,m;
int way[N];
void dfs(int u,int start)
{
    if( u+n-start < m) return;//剪枝
    if( u == m+1)
    {
        for(int i=1;i<=m;i++) printf("%d ",way[i]);
        puts("");
        return;
    }
    for(int i=start;i<=n;i++)
    {
        way[u]=i;
        dfs(u+1,i+1);
        way[u]=0;//恢复现场
    }
     
}
int main()
{
    scanf("%d%d",&n,&m);
    
    dfs(1,1);
    
    return 0;
}

94 递归实现排列型枚举

94. 递归实现排列型枚举 - AcWing题库

顺序1:依次枚举每个数放在哪个位置 ;

n个数放

顺序2:依次枚举每个位置哪个数。

递归搜索树,例如n=3,3个位置放三个数;

字典序最小,从小到大的进行输出,得到的字典序就是最小的;

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N=10;
int n;
int state[N];//0表示还未放数,1~n代表放过哪个数字
bool used[N];//true表示用过,false表示还没用过
void dfs(int u)
{
    if(u>n)  //边界
    {
        for(int i=1;i<=n;i++) printf("%d ",state[i]); //打印方案
        puts("");
        
        return ;
    }
    //依次枚举每个分支,即当前位置可以填哪些数
    for(int i=1;i<=n;i++)
    {
        if(!used[i])
        {
            state[u]=i;
            used[i]=true;
            dfs(u+1);
            
            //恢复现场
            state[u]=0;
            used[i]=false;
            
        }
    }
}
int main()
{
    scanf("%d",&n);
    
    dfs(1);
    return 0;
}

递推:

即通过已知条件,利用特定关系得出中间推论,直至得到结果的算法。

717 简单斐波那契

#include<cstring>
#include<iostream>
#include<algorithm>

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

116 飞行员兄弟

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>

using namespace std;

#define x first
#define y second
const int N=5;
typedef pair<int,int> PII;

char g[N][N],backup[N][N];

int get(int x,int y)
{
    return x*4+y;
}
void turn_one(int x,int y)
{
    if(g[x][y]=='-')  g[x][y]='+';
    else g[x][y]='-';
}
void turn_all(int x,int y)
{
    for(int i=0;i<4;i++)
    {
        turn_one(x,i);
        turn_one(i,y);
    }
    turn_one(x,y);
}
int main()
{
    vector <PII> res;
    for(int i=0;i<4;i++)  cin>>g[i];
    for(int op=0;op<1<<16;op++)
    {
        vector<PII> temp;
        memcpy(backup,g,sizeof g); //备份
        //进行操作
        for(int i=0;i<4;i++)
            for(int j=0;j<4;j++)
            {
                if(op>>get(i,j)&1){
                    temp.push_back({i,j});
                    turn_all(i,j);
                }
            }
        //判断
        bool has_closed=false;
        for(int i=0;i<4;i++){
            for(int j=0;j<4;j++)
            {
                if(g[i][j]=='+') has_closed= true;
            }
        }
        if(has_closed== false)
        {
            if(res.empty()||res.size()>temp.size()) res= temp;
        }
        memcpy(g,backup,sizeof g);//还原
    }
    cout<<res.size()<<endl;
    for(auto op:res) cout<<op.x+1<<' '<<op.y+1<<endl;
    return 0;
}

95 费解的开关95. 费解的开关 - AcWing题库

题解:AcWing 95. 费解的开关 - AcWing

1208 翻硬币

#include<iostream>
#include<cstring>
using namespace std;
const int N=110;

int n;
char start[N],aim[N];
void turn(int i)
{
    if(start[i]=='*')  start[i]='o';
    else start[i]='*';
}
int main()
{
    cin>>start>>aim;
    n=strlen(start);
    int res=0;
    for(int i=0;i<n-1;i++)
    {
        if(start[i]!=aim[i])
        {
            turn(i),turn(i+1);
            res++;
        }
    }
    cout<<res<<endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值