AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 应用
  • 更多
    • 题解
    • 分享
    • 商店
    • 问答
    • 吐槽
  • App
  • 登录/注册

AcWing 94. 递归实现排列型枚举    原题链接    简单

作者: 作者的头像   小小蒟蒻 ,  2020-07-01 12:28:42 ,  所有人可见 ,  阅读 716


3


1

题目描述 如题

递归树以及剪枝如图示:
微信图片_20200701132048.png

考虑递归函数的实现:
首先,观察样例输出。发现都是长度为3的一串数组。结合递归树,发现是在递归到f(3)才输出。之前的状态
都没有输出。体会到该处存在一个限制:递归参数u等于集合元素的总个数n的时候才能输出数字串。

该函数必然有输出模块,同时还有递归模块。输出模块是递归函数的出口。
递归模块可以通过在区间[0, n)上迭代递归函数本身。
于是,代码就长成了如下的样子:


先写出不剪枝的递归树对应的代码

C++ 代码

const int N = 10;
int a[N]; // 保存结果的集合 
int n;

void dfs(int u) {
    if(u == n) {
        for(int i = 0; i < n; i++)
            cout << a[i] << " ";
        puts("");
        return;
    }

    for(int i = 0; i < n; i++) {
        a[u] = i + 1;
        dfs(u + 1);
    }
}

输入样例:
3

输出样例:
n = 3的时候,输入就是递归树输出行的所有集合,3 ^ 3 = 27 个数字串。

对上面的代码剪枝

C++ 代码

const int N = 10;
int a[N], s[N], n;

void dfs(int u) {
    if(u == n) {
        for(int i = 0; i < n; i++)
            cout << a[i] << " ";
        puts("");
        return;
    }
    for(int i = 0; i < n; i++) {
        if(s[i]) continue;
        s[i] = 1;
        a[u] = i + 1;
        dfs(u + 1);
        s[i] = 0;
    }
}

输入样例:
3

输出样例:
n = 3时,输出递归树中所有蓝色的数字串。


总结:
样例给出的输出并不代表某种一般性的问题。可能得先解决一个更一般的问题。当然,这里可以体会到理解模板
熟记模板的重要性。熟记模板的前提是充分理解模板的实质!然后才是背板子,加快解决问题的速度。
搞清楚来龙去脉,最后才有复制粘贴板子的底气。

该问题的推广极简模板
void dfs(int u) {
    if(u == n) return;

    for(int i = 0; i < n; i++) 
        dfs(u + 1);
}

1 评论


用户头像
snkz5qing   2021-11-12 17:08         踩      回复

感谢大佬的分享,整明白了


你确定删除吗?
1024
x

© 2018-2023 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息