现在的位置: 首页 > 综合 > 正文

用递归实现排列组合

2013年09月18日 ⁄ 综合 ⁄ 共 1408字 ⁄ 字号 评论关闭

From:

 

http://dev.firnow.com/course/3_program/c++/cppjs/2008827/137778.html

 

 

用递归实现排列

“递归回溯”在排列中的主要思想

P(N,M)就相当于在一个M * N的棋盘上每行放一个棋子,且保证每列只有一个棋子. 
每一枚棋子都有N个位置可放, 因此就可以穷举每一个棋子的位置, 从第一行开始放,如果所放的列没放过棋子则从下一行的起始位置开始放, 否则放下一列, 如果已经没有位置可以放了, 则回溯(回退一行)...如果放下了M枚棋子,则所在的每枚棋子所在的列构成的序列即是一个满足要求的排列...

 

#include<stdio.h> 
#include<string.h> 

#define N 5 
#define M 3 

int used[N], count, b[M]; 
//used记录某个数是否被使用过,count记录解的个数,b记录每次所得的解 
void search( int ); 

int main() 

memset( used, 0, N * sizeof( used[0] ) ); 
search( 0 ); 
printf( "%d/n", count ); 
return 0; 

void search( int depth ) 

int i; 
if( depth == M )  //找到满足条件的解,则输出 

for( i = 0; i < M; i++ ) 
printf( "%d ", b[i] ); 
printf( "/n" ); 
count++; 
return; 

for( i = 0; i < N; i++ ) 

b[depth] = i + 1; 
if( !used[i] )  //检测是否被使用过 

used[i] = 1;  
search( depth + 1 ); 
used[i] = 0; 


}

depth是数组b的下标:取了数就加1, 否则就不变...

 

 

 

 

用递归实现组合:

“递归中分而治之的思想”在排列中的应用

从n个数取m个数的组合数,相当于就是用公式C(n,m) = C(n-1,m) + C(n-1,m-1)。

 

#include<stdio.h> 

#define N 5 
#define M 3 

void search( int, int, int ); 
int b[M], count;//数组b记录每次产生的解,count记录解的个数 
int main() 

count = 0; 
search( 0, N, M ); 
printf( "%d/n", count ); 
return 0; 

void search( int depth, int n, int m ) 

int i; 
if( m == 0 ) //满足条件则输出 

for( i = 0; i < M; i++ ) 
printf( "%d ", b[i] ); 
printf( "/n" ); 
count++; 
return ; 

if( m > n || n <= 0 ) return; //依常识剪枝 
b[depth] = n; 
search( depth + 1, n - 1, m - 1 ); 
b[depth] = 0; 
search( depth, n - 1, m ); 


抱歉!评论已关闭.