排列,组合问题

排列组合问题是一个运用递归的经典问题,我每次看到递归,脑袋就大,可是问题还是没办法逃避的,因此,认真学习一下关于排列组合问题的解法。


组合问题:

抽象描述:

总共有n个物体(在这里以数字1~n表示n个物体),选取r个物体,输出其排列顺序,以及个数。

算法描述:

  1. 我们从升序进行输出;因此最大的元素A的范围:r~n;
  2. 对于A(最大元素),考虑n,所有的序列可以被分成为两块:有n(n-r,r-1)和无n(n-1,r);
  3. 对于有n的情况,继续考虑n-1的情况; 对于无n的情况,继续考虑n-1的情况; 终止条件:n=r与n=0的情况;(如果n=r,那么剩下的元素只能是一一对应;如果n=1,那么直接输出序列)

代码描述:

#include<stdio.h>
#include<stdlib.h>

//n:剩余元素 r:待选元素个数
void DFS(int result[],int n,int r,int L,int* times){
    if(n==r){
        for(int i=0;i<r;i++){
            result[i]=i+1;
        }
        for(int j=0;j<L;j++){
            printf("%d ",result[j]);
        }
        printf("\n");
        (*times)++;
        return ;
    }
    else if(r==0){
        for(int i=0;i<L;i++){
            printf("%d ",result[i]);
        }
        printf("\n");
        (*times)++;
        return ;
    }
    else{
        result[r-1]=n; //选中n的情况
        DFS(result,n-1,r-1,L,times);  //分两种情况进行考虑!
        DFS(result,n-1,r,L,times);
    }
}

void main(){
    int n; //总物体数目
    int r; //挑选物体数目
    int i; //r~n:构成所有的情况
    int times=0;

    printf("请输入总物体的数目:");
    scanf("%d",&n);
    printf("请输入挑选物体的数目:");
    scanf("%d",&r);

    int result[r]; //记录路径
    int L=r; //为result[]记录数组长度

    DFS(result,n,r,L,&times);  //既要包含选择n的情况,也包含无n的情况;那么分为多层;通过回溯,递归。

    printf("所有情况的数目为: %d\n",times);
}

猜你喜欢

转载自blog.csdn.net/lansehuanyingyy/article/details/80411795