92. 递归实现指数型枚举

目录

92. 递归实现指数型枚举

输入格式

输出格式

数据范围

输入样例:

输出样例:

思路: 

代码:

运行结果:


92. 递归实现指数型枚举

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

输入格式

输入一个整数 nn。

输出格式

每行输出一种方案。

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

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

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

数据范围

1≤n≤151≤n≤15

输入样例:
3
输出样例:

3
2
2 3
1
1 3
1 2
1 2 3

思路: 


解题思路
 我们可以从 1 ~ n 依次考虑每个数选还是不选,我们可以以一个树的形式来描述选还是不选的情况。对于每一种情况有三种状态可以选择:待考虑、选、不选。我们以 0 表示待考虑,1 表示选该位,2 表示不选。比如当 n = 3 的时候,我们画出的递归搜索树如下:

 这其实就是一个 深度优先搜索 的过程,我们先考虑第一位,第一位有两种情况:左子树为不选第一位的情况,右子树为选第一位的情况;当不选第一位时又分成了两种情况,即在不选第一位的情况下第二位不选的情况(左子树)和第二位选的情况(右子树);然后又分成两种情况,选择第三位和不选择第三位。以上是整个左子树的分析情况,即刚开始第一位不选的情况。右子树第一位选择的情况下同理。

 所以我们可以使用 dfs 来递归遍历所有的情况,首先递归遍历不选的情况,然后再递归遍历选择的情况。当每层递归到结束时依次遍历我们记录每个点的状态,如果是 1 我们就输出该数,否则就不输出该数。


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

const int N = 16;

int n;
int st[N];//状态:记录每个位置当前的状态:0表示还没考虑,1表示选它。2表示不选它
vector<vector<int>> ways;

void dfs(int u){
    //判断边界
    if(u>n){ //u>n表示已经到最后一位了
    
    vector<int> way;
        for(int i=1;i<=n;i++)
        if(st[i]==1)
            way.push_back(i);
        ways.push_back(way);
        return;
        
    }
    
    st[u]=2;  //对于当前位置不选,置为 :2
    dfs(u+1); //到下一个位置 第一个分支:不选
    st[u]=0; //恢复现场
    
    st[u]=1;  //对于当前位置 选,置为 :1
    dfs(u+1);  //第二个分支:选
    st[u]=0;  //恢复现场
    
}
int main(){
    cin>>n;
    
    dfs(1);
    
    for(int i=0;i<ways.size();i++)
    {
        for(int j=0;j<ways[i].size();j++) printf("%d ",ways[i][j]);
        puts("");//输出回车
    }
    
    return 0;
}

        这段代码是一个经典的递归实现,用于从 1 到 n 这 n 个整数中随机选取任意多个,然后输出所有可能的选择方案。

        首先,在全局定义了一个常量 N 表示最大的整数个数,定义了一个数组 st 用来记录每个位置当前的状态:0 表示还没考虑,1 表示选它,2 表示不选它。同时定义了一个二维向量 ways 用来存储所有可能的选择方案。

接着有一个 dfs 函数,参数 u 表示当前处理的位置。在 dfs 函数中,首先判断是否已经到了最后一位,如果是,则将当前选取的数字存入 way 中,并将 way 存入 ways 中,表示找到了一种选择方案。然后进行递归调用,分别处理不选当前位置和选当前位置两种情况。

        在主函数 main 中,首先读入整数 n,然后调用 dfs(1) 开始递归搜索所有可能的选择方案。最后遍历 ways 向量,输出每一种选择方案。

        整体思路是通过递归的方式生成所有可能的选择方案,利用 st 数组来记录每个位置的选择状态,通过不断更新状态进行递归搜索。最终输出所有可能的选择方案。

运行结果:

 

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

captain_dong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值