1.分治法求全排列
void perm(char a[],int start,int end) { if(start==end) { printf("%s ",a); return; } else { for(int i=start;i<=end;i++) { swap(a[i],a[start]); perm(a,start+1,end); swap(a[i],a[start]); } } }
//有重复元素的 #include <iostream> #include <algorithm> #include <cstdio> #include<cstring> using namespace std ; int ok(char str[],int a ,int b ) { if(b>a) for(int i=a;i<b;i++) if(str[i]==str[b]) return 0; return 1; } void perm(char str[],int k,int m) { if(k==m) { printf("%s ",str); return ; } else for(int i=k;i<=m;i++) if(ok(str,k,i))//判断第i个元素是否在str[k,i-1]中出现过 { swap(str[k],str[i]); perm(str,k+1,m); swap(str[k],str[i]); } } int main() { char str[505]; scanf("%s",str); perm(str,0,strlen(str)-1); return 0; }
2.分治法求整数划分
int q(int n,int m) { if(n==1||m==1) return 1; else if(n<m) return q(n,n); else if(n==m) return 1+q(n,n-1); else return q(n,m-1)+q(n-m,m); }
//输出序列 #include <stdio.h> int mark[10]; int n; void Divid(int now,int k,int prio) { //now记录当前长度,k记录深度,prio记录前一个的值。 int i; if(now > n) return; //不合适,返回。 if(now == n) { for(i = 0; i < k-1; i++) printf("%d+",mark[i]); printf("%d ",mark[i]); } else { for(i = prio; i > 0; i--) { mark[k]=i; now+=i; Divid(now,k+1,i); now-=i; } } } int main() { scanf("%d",&n); Divid(0,0,n-1); return 0; }