原题链接
题目难度:简单
题目描述
从 $1 \sim n$ 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。
输入格式
输入一个整数 n。
输出格式
每行输出一种方案。
同一行内的数必须升序排列,相邻两个数用恰好 1 个空格隔开。
对于没有选任何数的方案,输出空行。
本题有自定义校验器(SPJ),各行(不同方案)之间的顺序任意。
数据范围
$1 \le n \le 15$
输入样例:
1 | 3 |
输出样例:
1 | 3 |
题目分析
这道题目的意思其实一目了然,然后我们可以根据数据范围选择出算法复杂度,实际上是$O(2^n)$级别即可
我们主要的思路就是需要确定从$1\sim n$中确定出这个数是选还是不选,因此所有的情况数就是$2^n$了
这道题的目的其实是训练我们递归的思想,对于递归(dfs)最重要的就是顺序,需要不重不漏的把所有可能的方案都顾及到,具体到这道题我们就只需要从$1\sim n$依次考虑选和不选的两种情况
这样我们就可以画一个递归树

这里我们也称之为递归搜索树,我们以三个数字为例,实际上是可以通过这种方法枚举出所有情况的,接下来的问题就是我们如何去实现,如何记录每一种情况下的状态
这里的状态我们有两种方法,一是开一个长度为$n$的数组,第二种方法就是利用位运算,将数位为1的位置标记为选中,将数位为0的位置标记为未选中
这里我们采用第一种方法来实现,因为比较直观容易理解
1 |
|
对于递归的情况,我们在回到上一步的时候,需要恢复原来的样子,不然再次进行操作时,可能会引出错误的情况,需要保持这个习惯,其次我们在写递归函数的时候,需要首先考虑何时递归结束