dfs/bfs
题单 :www.luogu.com.cn/contest/228…
递归(Recursion)
递归是指在函数的定义中,调用函数自身的编程技术。递归通常用于解决那些可以被分解为相似子问题的问题,特别适合用于树形结构、图结构的遍历,以及许多数学问题(如阶乘、斐波那契数列等)。
递归的基本结构
递归函数通常包含两个部分:
- 基准情况:递归结束的条件。当问题足够简单,无法继续递归时,直接返回结果。
- 递归情况:通过将问题分解为更小的子问题,递归调用自身来解决。
递归的经典例子:阶乘
阶乘函数 n! 表示从 1 到 n 的所有整数相乘,即:
- 0! = 1
- n! = n × (n-1)!
递归实现阶乘的函数:
int factorial(int n) {
// 基准情况:当 n 为 0 时,返回 1
if (n == 0) {
return 1;
}
// 递归情况:n! = n * (n-1)!
return n * factorial(n - 1);
}
递归例题
P5739 【深基7.例7】计算阶乘
使用递归求阶乘
long long solve(int n){
if(n == 1) return 1LL;
return n * solve(n - 1);
}
斐波那契数列
long long fib(int x) {
if(x == 1 || x == 2) return 1LL;
return fib(x - 1) + fib(x - 2);
}
U523555 数数小木块
// f(n) 表示第 n 层有多少块小木块
// f(n) = f(n - 1) + n
int f(int n) {
if(n == 1) return 1;
return f(n - 1) + n;
}
void solve(){
int n, s = 0;
cin >> n;
for(int i = 1; i <= n; i ++){
s += f(i);
}
cout << s;
}
dfs枚举子集
B3622 枚举子集(递归实现指数型枚举)
int n, p[15];
void dfs(int x) {
if(x == n + 1) {
for(int i = 1; i <= n; i ++){
cout << (p[i] ? 'Y' : 'N');
}
cout << '\n';
return ;
}
for(int i = 0; i <= 1; i ++) {
p[x] = i;
dfs(x + 1);
}
}
开始 (x = 1)
/ \
p[1]=0 p[1]=1
| |
x=2 x=2
/ \ / \
p[2]=0 p[2]=1 p[2]=0 p[2]=1
| | | |
N N N Y Y N Y Y
练习题
int n, k, res;
int a[20];
bool check(int x) {
if(x == 1) return false;
for(int i = 2; i <= x / i; i ++) {
if(x % i == 0) return false;
}
return true;
}
/**
* parameters : int x, int cnt, int sum
* 来到第 x 层, 选了 cnt 个数, 和为 sum
*/
void dfs(int x, int cnt, int sum) {
if(x == n + 1) {
if(cnt == k) res += check(sum);
return ;
}
dfs(x + 1, cnt + 1, sum + a[x]);
dfs(x + 1, cnt, sum);
}
void solve(){
cin >> n >> k;
for(int i = 1; i <= n; i ++){
cin >> a[i];
}
dfs(1, 0, 0);
cout << res;
}
dfs 求全排列
P1706 全排列问题
int n, st[25], p[25];
void dfs(int x) {
if(x == n + 1) {
for(int i = 1; i <= n; i ++){
cout << setw(5) << p[i];
}
cout << '\n';
return ;
}
for(int i = 1; i <= n; i ++){
if(!st[i]) {
st[i] = 1;
p[x] = i;
dfs(x + 1);
st[i] = 0;
}
}
}