1.分治法求全排列
void perm(char a[],int start,int end)
{
if(start==end)
{
printf("%s\n",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\n",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\n",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;
}