数学问题-排列组合
组合序列:
void conbination(int n,int m,int a[],int b[],const int &M){ for(int j=m;j<=n;j++){ b[m-1]=a[j-1]; if(m>1) conbination(j-1,m-1,a,b,M); else{ for(int i=0;i<M;i++) printf("%d ",b[i]); printf("\n"); } } }
递归图解:
全排列:
void swap(int *p1,int *p2){ int t=*p1; *p1=*p2; *p2=t; } void full_permutation(int a[],int t,int size){ if(t==size){ for(int i=0;i<size;i++) printf("%d ",a[i]); printf("\n"); } else{ for(int j=t;j<size;j++){ swap(&a[j],&a[t]); full_permutation(a,t+1,size);//此处用到递归思想 swap(&a[j],&a[t]); } } }
将组合后的序列进行全排列,就得到了排列序列:
排列序列:
void permutation(int n,int m,int a[],int b[],const int &M){ for(int j=m;j<=n;j++){ b[m-1]=a[j-1]; if(m>1) permutation(j-1,m-1,a,b,M); else{ full_permutation(b,0,M); } } }
测试代码:
#include <stdio.h> #include <memory.h> #include <math.h> #include <string.h> #include <string> #include <vector> #include <set> #include <stack> #include <queue> #include <algorithm> #include <map> #define I scanf #define OL puts #define O printf #define F(a,b,c) for(a=b;a<c;a++) #define FF(a,b) for(a=0;a<b;a++) #define FG(a,b) for(a=b-1;a>=0;a--) #define LEN 100 #define MAX 0x06FFFFFF #define V vector<int> using namespace std; void conbination(int n,int m,int a[],int b[],const int &M){ for(int j=m;j<=n;j++){ b[m-1]=a[j-1]; if(m>1) conbination(j-1,m-1,a,b,M); else{ for(int i=0;i<M;i++) printf("%d ",b[i]); printf("\n"); } } } void swap(int *p1,int *p2){ int t=*p1; *p1=*p2; *p2=t; } void full_permutation(int a[],int t,int size){ if(t==size){ for(int i=0;i<size;i++) printf("%d ",a[i]); printf("\n"); } else{ for(int j=t;j<size;j++){ swap(&a[j],&a[t]); full_permutation(a,t+1,size);//此处用到递归思想 swap(&a[j],&a[t]); } } } void permutation(int n,int m,int a[],int b[],const int &M){ for(int j=m;j<=n;j++){ b[m-1]=a[j-1]; if(m>1) permutation(j-1,m-1,a,b,M); else{ full_permutation(b,0,M); } } } int main(){ int n=5,m=3; int a[n];int b[m]; for(int i=0;i<n;i++) a[i]=i+1; const int M=m; puts("组合序列"); conbination(n,m,a,b,M); puts("全排列"); full_permutation(a,0,n); puts("排列序列"); permutation(n,m,a,b,M); return 0; }
测试效果:
组合序列应用实例:
OJ链接:P1036 选数
AC代码:
#include <iostream> #include <stdio.h> #include <memory.h> #include <math.h> #include <string> #include <vector> #include <set> #include <stack> #include <queue> #include <algorithm> #include <map> #include <numeric> #define I scanf #define OL puts #define O printf #define F(a,b,c) for(a=b;a<c;a++) #define FF(a,b) for(a=0;a<b;a++) #define FG(a,b) for(a=b-1;a>=0;a--) #define LEN 1010 #define MAX (1<<30)-1 #define V vector<int> using namespace std; int N,K; int num[LEN]; int res[LEN]; int ans=0; bool isPrime(int x){ if(x<2) return 0; for(int i=2;i<sqrt(x);i++){ if(x%i==0) return 0; } return 1; } void conbination(int n,int m,int *a,int *b){//C(n,m) int i,j; for(i=m;i<=n;i++){ res[m-1]=num[i-1]; if(m>1) conbination(i-1,m-1,a,b); else{ int sum=accumulate(res,res+K,0); if(isPrime(sum)){ // FF(j,K) cout<<res[j]<<' '; // cout<<endl; ans++; } } } } int main(){ // freopen("选数.txt","r",stdin); I("%d%d",&N,&K); int i; FF(i,N) cin>>num[i]; conbination(N,K,num,res); cout<<ans<<endl; return 0; }
2.排列组合公式
排列公式 P(n,m)=n!/(n-m)!
代码:
int P(int n,int m){ int p=1; while(m){ p*=n; n--; m--; } return p; }
代码理解:其实就是累乘,nx(n-1)x(n-2)x……x(m+1)x(m)
--------------------------------------------------
组合公式 C(n,m)=P(n,m)/m!=n!/[m!(n-m)!]
int C(int n,int m){ int i,c=1; i=m; while(i){ c*=n; n--; i--; } while(m){ c/=m; m--; } return c; }
代码理解:先求出P(n,m),再计算P(n,m)/m!