acwing-蓝桥杯C++ AB组辅导课Day1-递归

感谢梦翔老哥的蓝桥杯C++ AB组辅导课~

省一刷200题        国赛拿成绩300题

比赛考察的是各种模型的熟练度,可以从dfs的角度比较各个模型与当前问题的匹配程度。

常见时间复杂度,根据时间复杂度可以判别是否可以选用这个解题思路

acwing-蓝桥杯C++ AB组辅导课Day1-递归_第1张图片

 写递归的时候,可以考虑将递归写成递归搜索树的形式,比较便于理解:

acwing-蓝桥杯C++ AB组辅导课Day1-递归_第2张图片

常见的数字:

acwing-蓝桥杯C++ AB组辅导课Day1-递归_第3张图片

递归实现指数型枚举:

acwing-蓝桥杯C++ AB组辅导课Day1-递归_第4张图片

递归的思路就是找到一个顺序不重不漏的遍历所有情况。本题的思路就是遍历每个位置,考虑每个位置选或不选的情况。

acwing-蓝桥杯C++ AB组辅导课Day1-递归_第5张图片

ac代码:

从第0个位置开始枚举,到第n-1的位置。先写边界,边界写完可以考虑上面图中的某个节点(红圈),设置某个位置的数字后递归回溯要还原现场。

递归是怎么实现回溯的呢?看下列代码,dfs(u+1)的位置,执行到此处代码会进入到新的函数当中,当dfs(u+1)执行结束的时候,会跳转到目前执行的下一行,为了不影响“选”的决策,需要把位置设置为原来的0。建议与上面的红圈图搭配着看比较清晰。

其实本题可以不用恢复现场,并且state[u] = 0 会被state[u] = 1 和下次dfs中的status[u]=2覆盖掉,因为最后输出只在递归树的末端,此时所有的位置都是1或者2,没有0。
acwing-蓝桥杯C++ AB组辅导课Day1-递归_第6张图片

递归实现排列型枚举:

做递归题建议先把递归搜索树写出来,明确思路。会简单很多。

acwing-蓝桥杯C++ AB组辅导课Day1-递归_第7张图片

思路1:枚举每个数字放到哪个位置 ×        由于题目要求输出字典序较小的数字,模拟了一下发现不能满足题目要求。

思路2:枚举每个位置放哪个数字 √

递归搜索树
acwing-蓝桥杯C++ AB组辅导课Day1-递归_第8张图片

AC代码:

acwing-蓝桥杯C++ AB组辅导课Day1-递归_第9张图片

时间复杂度分析:

根据递归搜索树分析,第一层O(n),第二层nxn,第三层nx(n-1)xn...        视频后面还有个证明,大概是使用了放缩,将红框的内容全部加起来,提出来个n,剩余的部分可以放缩成小于等于3倍的n!。所以最终的时间复杂度为nxn!。
acwing-蓝桥杯C++ AB组辅导课Day1-递归_第10张图片

习题1:

递归实现组合型枚举

acwing-蓝桥杯C++ AB组辅导课Day1-递归_第11张图片

思路:

一开始看到这个题,感觉跟例题里的枚举每个位置放哪个数基本一致,以为稍微改一下数组大小就行。但题意要求输出升序序列。所以在这基础上需要进行剪枝,123是可以的,132就是不行的。所以在填写位置的时候,将目前已经填写的数字(3)与即将要填入的数字(2)进行比较,如果已经填写的数字大于即将填入的数字,那就不能填,再往后看看有没有合适的数。

AC代码:

#include

using namespace std;

vector ans;
bool state[26];

int m,n;    //m表示位置个数,n表示数字个数

void dfs(int u){//枚举位置
    
    if(u == m){
        for(int i=0;inum)){
            ans.push_back(i);
            state[i] = true;
            dfs(u+1);
            ans.pop_back();
            state[i] = false;
            
        }
    }
    
    
}

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

习题2:带分数

acwing-蓝桥杯C++ AB组辅导课Day1-递归_第12张图片

自己没想出来,引用一下人家的题解(没想到竟然如此暴力):
acwing-蓝桥杯C++ AB组辅导课Day1-递归_第13张图片

代码如下(代码自己想着敲得):

#include

using namespace std;
vector ans;
bool status[10];
int cnt = 0;
int calc(int i,int j){
    int num = ans[i];
    while(i


 

你可能感兴趣的:(蓝桥杯,c++,职场和发展)