01递归实现指数型枚举
从 1∼n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。
输入格式
输入一个整数 n。
输出格式
每行输出一种方案。
同一行内的数必须升序排列,相邻两个数用恰好 1 个空格隔开。
对于没有选任何数的方案,输出空行。
本题有自定义校验器(SPJ),各行(不同方案)之间的顺序任意。
数据范围
1≤n≤15
输入样例:
3
输出样例:
3
2
2 3
1
1 3
1 2
1 2 3
思路:
每个数字都有选或者不选两个选择,所以就有 2^n 个可能性
方法一:非递归型状态压缩
首先我们将每一种可能都用二进制表示,那么如下
0 0 0 []
0 0 1 [1]
0 1 0 [2]
0 1 1 [1,2]
1 0 0 [3]
1 0 1 [1,3]
1 1 0 [2,3]
1 1 1 [1,2,3]
那么我们枚举所有的状态,将结果打印出来即可
代码如下
#include<bits/stdc++.h> using namespace std; int n; int main(){ cin>>n; //遍历所有状态 for(int i=0; i< 1<<n; i++){ //遍历状态的各个位数 for(int j=0; j<n; j++){ if(i >> j & 1){ cout << j+1 << " "; } } cout << endl; } return 0; }
方法二:状态压缩递归:(来自b站大雪菜大佬的题解)
利用递归的方式来进行状态的遍历
代码:
#include<bits/stdc++.h> using namespace std; int n; void dfs(int a, int state){ if(a == n){ //遍历当前状态的各个位数 for(int i=0; i<n; i++){ if(state >> i & 1){ cout << i+1 << " "; } } cout << endl; return; } dfs(a+1, state); //不选 dfs(a+1, state | (1<<a)); //选 } int main(){ cin>>n; //从第一个数开始,状态为不选 0 dfs(0,0); return 0; }

浙公网安备 33010602011771号