跟着姚桑学算法-递归实现组合型枚举

简介: 基本算法题

基本算法题. 递归实现组合型枚举

从 1∼n 这 n 个整数中随机选出 m 个,输出所有可能的选择方案。

输入格式
两个整数 n,m ,在同一行用空格隔开。

输出格式
按照从小到大的顺序输出所有方案,每行 1 个。

首先,同一行内的数升序排列,相邻两个数用一个空格隔开。

其次,对于两个不同的行,对应下标的数一一比较,字典序较小的排在前面(例如 1 3 5 7 排在 1 3 6 8 前面)。

数据范围
n>0 ,
0≤m≤n ,
n+(n−m)≤25

输入样例:

5 3

输出样例:

1 2 3 
1 2 4 
1 2 5 
1 3 4 
1 3 5 
1 4 5 
2 3 4 
2 3 5 
2 4 5 
3 4 5 

思考题: 如果要求使用非递归方法,该怎么做呢?

:four_leaf_clover:题解 --- 递归

所谓的组合型枚举,就是枚举的结果与顺序无关,只与组合它的数有关;
没错,这就是典型的从n个中选m个的问题。

只要按照升序枚举的话,所有的结果也是按照升序排序的,并且因为是与顺序无关,不需要去标记哪个数被用过,能不能枚举,只需要记录一下选择的数。

可以看出某一个点的子树其选过的数都是相同的,那么是不是可以记录选择的个数的同时记录一下从哪个数继续枚举下去。

纵观整棵树,不难发现根节点后面几颗子树会出现枚举不了的情况,并且随着n、m的增大,这种情况会越来越多。那有办法能够省去这些判断吗?

剪枝 ,dfs里非常常见,顾名思义就是将不需要的枝条剪去,也就是递归搜索树的不符合条件的子树或者分支。如本题,如果当前选的数加上剩下可以选的数还是不足需要的数,那么直接结束这一分支的搜索。

:memo:代码展示

#include <iostream>

using namespace std;

const int N = 35;

int n , m;
int st[N];

void dfs(int u , int start) {
    if (u + n - start < m) return;  // 剪枝 u - 1 + n - start + 1 < m
    if(u > m) {
        for(int i = 1; i <= m; i ++) cout << st[i] << " ";
        cout << endl;

        return;
    }

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

}

int main() {

    cin >> n >> m;

    dfs(1 , 1);

    return 0;
}

【知识点:递归】

反复的回顾算法本质,厚积薄发:

递归 问题:
作为一种解决问题的有效方法,在递归过程中,函数将自身作为子例程调用。
递归的思想是 把一个大型复杂问题层层转化为一个与原问题规模更小的问题,问题被拆解成子问题后,递归调用继续进行,直到子问题无需进一步递归就可以解决的地步为止。

目录
相关文章
|
5月前
|
算法 C++
算法笔记:递归(c++实现)
算法笔记:递归(c++实现)
|
28天前
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
18 1
|
5月前
|
存储 算法 程序员
数据结构与算法===递归
数据结构与算法===递归
|
28天前
|
算法 定位技术
数据结构与算法学习九:学习递归。递归的经典实例:打印问题、阶乘问题、递归-迷宫问题、八皇后问题
本文详细介绍了递归的概念、重要规则、形式,并展示了递归在解决打印问题、阶乘问题、迷宫问题和八皇后问题等经典实例中的应用。
33 0
|
3月前
|
算法
【算法】递归、搜索与回溯——汉诺塔
【算法】递归、搜索与回溯——汉诺塔
|
3月前
|
算法
【算法】递归总结:循环与递归的区别?递归与深搜的关系?
【算法】递归总结:循环与递归的区别?递归与深搜的关系?
|
3月前
|
算法
【算法】递归、搜索与回溯——简介
【算法】递归、搜索与回溯——简介
|
4月前
|
算法 Python
python中算法递归错误(Recursion Errors)
【7月更文挑战第18天】
69 1
|
5月前
|
机器学习/深度学习 算法 C语言
详细介绍递归算法在 C 语言中的应用,包括递归的基本概念、特点、实现方法以及实际应用案例
【6月更文挑战第15天】递归算法在C语言中是强大力量的体现,通过函数调用自身解决复杂问题。递归涉及基本概念如自调用、终止条件及栈空间管理。在C中实现递归需定义递归函数,分解问题并设定停止条件。阶乘和斐波那契数列是经典应用示例,展示了递归的优雅与效率。然而,递归可能导致栈溢出,需注意优化。学习递归深化了对“分而治之”策略的理解。**
105 7
|
5月前
|
算法 前端开发 Java
探讨Java中递归构建树形结构的算法
探讨Java中递归构建树形结构的算法
60 1