基本概念步骤优缺点典型例题
递推
基本概念
直接或者间接调用自身的算法称为递归算法
一般数据 n<=30用递归
步骤 优缺点 优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性。因此它为设计算法、调试程序带来很大方便。
缺点:运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。
- 求 n 的阶乘求 斐波那契数列求 二叉树相关内容 ⭐汉诺塔问题排列 问题
ACWing 练习题
717. 简单斐波那契
#include#include #include #include using namespace std; int n; int a,b=1,c; int main() { scanf("%d",&n); while(n--){ printf("%d ",a); c=a+b; a=b,b=c; } return 0; }
92. 递归实现指数型枚举
#include#include #include using namespace std; const int N = 16; int n; int status[N];//0 表示未使用 1表示选中 2表示未选中 void dfs(int u) { if(u > n)//判断边界 { for (int i = 1; i <= n; i ++ ) { if(status[i]==1) cout<>n; dfs(1); return 0; }
94. 递归实现排列型枚举
#include#include #include using namespace std; const int N = 10; int n; int sta[N];//表示位置 0 未使用 1 ~ n 放了数 bool used[N];//默认是0 0 是未使用 1 是已使用 void dfs(int u) { if (u > n) { for(int i = 1; i <= n;i++) printf("%d ",sta[i]); puts(""); return; } for (int i = 1; i <= n; i ++ )//遍历枚举分支 因为有多个分支 { if(!used[i]) { used[i]=true; sta[u]=i;//把该数放入 dfs(u+1); used[i]=false;//恢复现场 sta[u]=0; } } } int main() { cin>>n; dfs(1); return 0; }
93. 递归实现组合型枚举
#include#include #include using namespace std; const int N = 30; int n,m; int sta[N]; void dfs(int u,int start) { if(u+n-start >n>>m; dfs(1,1); return 0 ; }
1209. 带分数(难)⭐⭐⭐
暴力可以做
优化一下 dfs嵌到也可以做 但是费时
思路
看成三个数,根据公式能推出 cn=ca+b,因此只需求出c和a就能得出b 缩小了复杂度
因此先 枚举a,然后枚举c,最后判断b是否成立
#includeusing namespace std; const int N = 10; int n, ans; bool st[N]; //记录是否使用 bool backup[N]; //备份数组 bool check(int a, int c) //求 b 的值,并且判断没有重复 而且和符合要求 { long long b = n * (long long)c - a * c; if (!a || !b || !c) //都不为0 return false; memcpy(backup, st, sizeof st); //复制数组 while (b) { int x = b % 10; //取个位数 b /= 10; //缩小 if (!x || backup[x]) //判断 x 是否为0 或是 x 是否被用过 return false; backup[x] = true; } for (int i = 1; i <= 9; i++) //看b 有没有重复的 if (!backup[i]) return false; return true; } void dfs_c(int u, int a, int c) { if (u > 9) //如果十个数都用了 return; if (check(a, c)) //看是否符合要求 ans++; for (int i = 1; i <= 9; i++) { if (!st[i]) { st[i] = true; dfs_c(u + 1, a, c * 10 + i); st[i] = false; //恢复现场 } } } void dfs_a(int u, int a) { if (a >= n) //这不是边界 return; if (a) dfs_c(u, a, 0); for (int i = 1; i <= 9; i++) { if (!st[i]) { st[i] = true; dfs_a(u + 1, a * 10 + i); st[i] = false; } } } int main() { cin >> n; dfs_a(0, 0); //第一个表示当前位置 第二个是a的值 cout << ans << endl; return 0; }



