dfs/bfs基础

115 阅读2分钟

dfs/bfs

题单 :www.luogu.com.cn/contest/228…

递归(Recursion)

递归是指在函数的定义中,调用函数自身的编程技术。递归通常用于解决那些可以被分解为相似子问题的问题,特别适合用于树形结构、图结构的遍历,以及许多数学问题(如阶乘、斐波那契数列等)。

递归的基本结构

递归函数通常包含两个部分:

  1. 基准情况:递归结束的条件。当问题足够简单,无法继续递归时,直接返回结果。
  2. 递归情况:通过将问题分解为更小的子问题,递归调用自身来解决。

递归的经典例子:阶乘

阶乘函数 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);
}

斐波那契数列

www.luogu.com.cn/problem/B20…

long long fib(int x) {
    if(x == 1 || x == 2) return 1LL;
    return fib(x - 1) + fib(x - 2);
}

U523555 数数小木块

image

// 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 枚举子集(递归实现指数型枚举)

www.luogu.com.cn/problem/B36…

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

练习题

www.luogu.com.cn/problem/P10…

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 全排列问题

www.luogu.com.cn/problem/P17…

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;

        }

    }

}