用C++求出组合个数and具体的组合数据

本文介绍了如何通过递归方法解决从给定数组中获取所有可能组合的问题,而非仅计算组合总数。作者以三选二为例,展示了一个简单的递归框架,并给出了C++代码实现,该代码能够生成所有可能的排列并存储于二维数组中。
摘要由CSDN通过智能技术生成

关于题目

题目描述:取n个数组成为数组,从其中取m个数字组成一个组合,共有多少个这样的组合,并把具体的组合列举出来。

  • 看完题目很多人开始从公式着手得出组合数即
    C n m C_{n}^{m} Cnm得出结果,或者用 C n m = C n − 1 m + C n − 1 m − 1 C_{n}^{m}=C_{n-1}^{m}+C_{n-1}^{m-1} Cnm=Cn1m+Cn1m1采用递归方法得出组合数。

可是有没有想过要是这样那如何得出组合的具体数据呢?

关于解题

所以我跳开了公式,采取最简单粗暴的方法来递归。
我以{1,2,3} C 3 2 C_{3}^{2} C32来举例:

1
2
1,2
1,3
2,3

那么以这个为思想我们可以写出暴力递归的基本框架了:

/*参数:需要组合的数组s,
临时存放排列数组的temp,
排列数需要满足的长度k,
以及用以控制每次递归循环的开始处x,
用于存放答案的二维数组res
*/
void dfs()
{
//递归触底的条件
 if(temp的长度等于k){
        将temp序列放入res中;
        return;
    }

    for(int i=x;i<s数组的元素个数;i++){
        将s[i]存入数组temp中;
        dfs(temp,s,k,i+1);
        当dfs触底后将数组temp的最后一个元素弹出;
    }
    
}

我这样写也是为了让没有C++基础的同学看懂。。
下面我将介绍详细代码

关于代码

/*
s一维数组用于存储需要排列的数字。
res二维数组用于存储每次具体的排列。
temp一维数组用于存储每个排列数的数字。
*/
#include<bits/stdc++.h>
using namespace std;
vector<vector<int>>res;
vector<int>temp;
vector<int>s;
//dfs函数用于遍历s中的数字,然后创建对应的答案填入res中。
/*
参数k表示每个排列需要多少个数字,即从n个数字中取m个数字组成排列中的m
参数x用于让子问题不重复,即1,2,3取两个数,我们先从1开始然后得出1,2和1,3而不会有1,1
同理从2开始也只会有2,3,这就是每次递归时参数x取i+1的缘由

既然是递归解决,兄弟们还是老老实实把递归树先画出来吧。。。
*/
void dfs(vector<int>&temp,vector<int>&s,int k,int x){
	if(temp.size()+s.size()-x<k)return;
	//判断子情况是否能满足k个元素
    if(temp.size()==k){
        res.push_back(temp);
        return;
    }

    for(int i=x;i<s.size();i++){
        temp.push_back(s[i]);
        dfs(temp,s,k,i+1);
        temp.pop_back();
    }
    
}
int main(){
    //输入n个数字,并从n个数字中取m个数字组成排列
    int n;
    int m;
    int h;
    cin >> n>>m;
    for(int i=0;i<n;i++){
        cin >>h;
        s.push_back(h);
    }
    dfs(temp,s,m,0);//递归建立res数组得出答案
     printf("There are %d groups of permutations.\n",res.size());//输出得出多少个排列数
    cout << "The specific number of permutations is:"<<endl;//输出具体的排列数字
    for(int j=0;j<res.size();j++){
        for(int q:res[j])
        {cout<<q<<',';}
        cout<<'\n';
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值