C(n,m)的组合问题
来源:互联网 发布:华为人工智能芯片手机 编辑:程序博客网 时间:2024/05/22 01:51
- void comb_back(int a[],int m,int r)
- {
- int i,j,k=0;
- i=0,a[i]=1;
- do
- {
- if (a[i]-i<=m-r+1)
- {
- // 相等就找到组合
- if (i==r-1)
- {
- printf( "第%d组: ",++k);
- for(j=0;j <r;j++)
- printf( "%d ",a[j]);printf( "/n ");
- // 最后的一个元素加1
- a[i]++;
- continue;
- }
- i++; //向前试探
- a[i]=a[i-1]+1;
- }
- else
- {
- //回溯
- if(i==0)
- return;//已找到了全部解
- a[--i]++;
- }
- }while(1);
- }
- // Function:从n个数中选择m个数进行组合的非递归算法。
- /*
- 首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。
- 然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为
- “01”组合,同时将其左边的所有“1”全部移动到数组的最左端。
- 当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得
- 到了最后一个组合。
- 例如求5中选3的组合:
- 1 1 1 0 0 //1,2,3
- 1 1 0 1 0 //1,2,4
- 1 0 1 1 0 //1,3,4
- 0 1 1 1 0 //2,3,4
- 1 1 0 0 1 //1,2,5
- 1 0 1 0 1 //1,3,5
- 0 1 1 0 1 //2,3,5
- 1 0 0 1 1 //1,4,5
- 0 1 0 1 1 //2,4,5
- 0 0 1 1 1 //3,4,5
- */
- #include "stdafx.h"
- #include <stdio.h>
- #include <stdlib.h>
- void C(int N, int M, int *Num)
- {
- int i;
- bool ifok = false;
- // 10前面连续0的个数
- int iZero = 0;
- // 10前面连续1的个数
- int iOne = 0;
- // 初始化第一个组合
- for (i=0; i<M; i++)
- {
- Num[i] = 1;
- printf("%d", i+1);
- }
- printf("/n");
- // N-M个数为0
- for (i=M; i<N; i++)
- Num[i] = 0;
- if (M == N)
- ifok = true;
- while(!ifok)
- {
- iOne = 0;
- iZero = 0;
- // 从第一个数开始找10
- for (i=0; i<N; i++)
- {
- // 找到10
- if ( 1 == Num[i] && 0 == Num[i+1])
- {
- Num[i] = 0;
- Num[i+1] = 1;
- break;
- }
- // 找到1且下一个不是0
- else if (1 == Num[i] && 0 != Num[i+1])
- {
- iOne++;
- }
- // 计算连续0的个数
- else if (0 == Num[i])
- {
- iZero++;
- }
- }
- if (iZero)
- {
- // 把左边的所有1移到左端
- for (i=0; i<iOne; i++)
- {
- Num[i] = 1;
- }
- for (i=iOne; i<iOne+iZero; i++)
- {
- Num[i] = 0;
- }
- }
- // 输出结果
- for (i=0; i<N; i++)
- {
- if (Num[i] == 1)
- printf("%d", i+1);
- }
- // 换行
- printf("/n");
- // 判断是否输出了所有的组合
- for (i=N-M; i<N; i++)
- {
- if (0 == Num[i])
- break;
- }
- if (Num[N-1] != 0 && i == N)
- ifok = true;
- }
- }
- int main(void)
- {
- int N;
- int M;
- scanf("%d%d", &N, &M);
- int *Num = (int *)malloc(sizeof(int)*N);
- C( N, M,Num);
- free(Num);
- return 0;
- }
- // 递归算法
- /// 求从数组a[1..n]中任选m个元素的所有组合。
- /// a[1..n]表示候选集,n为候选集大小,n>=m>0。
- /// b[1..M]用来存储当前组合中的元素(这里存储的是元素下标),
- /// 常量M表示满足条件的一个组合中元素的个数,M=m,这两个参数仅用来输出结果。
- void combine( int a[], int n, int m, int b[], const int M )
- {
- for(int i=n; i>=m; i--) // 注意这里的循环范围
- {
- b[m-1] = i - 1;
- if (m > 1)
- combine(a,i-1,m-1,b,M);
- else // m == 1, 输出一个组合
- {
- for(int j=0; j<M; j++)
- printf("%d", a[b[j]]);
- printf("/n");
- }
- }
- C(n,m)的组合问题
- 求C(n,m)组合问题
- 组合C(m,n)
- 组合c(m,n)的计算方法
- 组合c(m,n)的计算方法
- 组合c(m,n)的计算方法
- 组合数C(n,m)的计算
- 组合c(m,n)的计算方法
- 组合问题:全组合和C(n,m)
- 组合数C(n,m)
- m选n组合问题
- 计算组合公式C(n,m)的化简
- 组合数C(n,m)的求法总结,卢卡斯定理
- 枚举C(n,m)组合的算法集锦
- 组合数算法 C(n,m)(n>=m)
- m个数取n个进行组合 C m n
- 计算组合数C(m,n)
- 变态组合数C(n,m)求解
- `basename $0` 与$0区别
- 一见钟情于PHP
- 小知识
- [转] 文件内容查看 cat,less,more,tail,head,sed
- .net学习感悟
- C(n,m)的组合问题
- 自己的学习笔记
- 学习笔记1
- 好
- 操作系统之进程--基础知识
- 常识
- 操作系统之线程、对称多处理器和微内核--基础知识
- 搜索引擎的使用技巧
- 出来乍到