组合求解--递归法

 类循环组合排序:  有M个数  每个数有N种可能
 如:4  2     0000 0001 0010 0011 0100.....1110 1111
利用递归的思想:

   可以把它现象成一颗树:一颗子树数相同的数:
       由于每一层有做相同的子树所以再递归函数中有
       for(int i;i
      循环代表递归函数中有多少个子树是要用到调用自身函数的即用for来实现多个有N个
      在每个子树中的情况都一样,自是它的层数I+1了,由于有M个数所以它是有M-1层的
      所以它的出口时:I>M,就把mat[i]输出来

void solve(int l){
if(l>=n){
for(int i=0;i<n;++i)printf("%d", mat[i]);
puts("");
return;
}
for(int i=0;i<m;++i){
mat[l]=i;
solve(l+1);
}
}
solve(0);//函数调用,是代表从第一层开始

全组合排序:这个和上一个有一点不同那就是子树的点不能和父点相同,即一个分支的组合数不能相同

只要在for(i<0;i
if(!used[i]){//是个标记为了把上层已经用过的点去除掉
        used[i]=1;
        num[I]=mat[i];//mat为输入的数;num为输出的数;
        solve(I+1);//下一层;了
        used[i]=0;//代表一个分支对另一个分支不影响,所以要初始化回来;
}

}

非重复组合排序(含有重复数字时,生成不重复组合排序)


只要为重复的数当成一个数来处理,但是这个数可以用多次每次用完即减一就可以了,其它的和全组合是一样的。






普通选择性排序:它是在M个数中选N个数进行完全排列  如数学中的C(N,M)

#include
#include
#include
void conbination(int I,int start);
int m,n;
int *in,*out;
void conbination(int I,int start){//I代表层数  start代表一层从哪个数开始
int j,i;
        if(I>=n){//当到了第N层时是出口
             for(j=0;j
             printf("\n"); 
      return;
}
           
  for(i=start;i<=m-n+I;i++){  //start一层中第一个数,m-n+I代表一层中最后一个数
  out[I]=in[i];//把的到的数赋值给输出
        conbination(I+1,i+1);//下一层,并且是从上次的开始下一位作为开始进行递归了。
}


}
void main(){
        int i;
        scanf("%d,%d",&m,&n);
        in=(int *)malloc(sizeof(int)*m);   
        out=(int *)malloc(sizeof(int)*m);
        for(i=0;i
            scanf("%d",&in[i]);
        memset(out,0,sizeof(int)*m);
        conbination(0,0);   

    
      free(in);
      free(out);
}

//今天总结到这,下次有空再继续


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值