01递归实现指数型枚举

从 1n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。

输入格式

输入一个整数 n。

输出格式

每行输出一种方案。

同一行内的数必须升序排列,相邻两个数用恰好 1 个空格隔开。

对于没有选任何数的方案,输出空行。

本题有自定义校验器(SPJ),各行(不同方案)之间的顺序任意。

数据范围

1n15 

输入样例:

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;
}

 

posted @ 2021-11-02 23:43  爱慕6  阅读(74)  评论(0)    收藏  举报