拆分自然数的几种算法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

拆分自然数的几种算法

【问题描述】自然数的拆分:任何一个大于1的自然数N,总可以拆分成若干个自然数之和,并且有多种拆分方法。例如自然数5,可以有如下一些拆分方法:

【问题描述】自然数的拆分:任何一个大于1的自然数N,总可以拆分成若干个自然数之和,并且有多种拆分方法。例如自然数5,可以有如下一些拆分方法:

5=1+1+1+1+1

5=1+1+1+2

5=1+2+2

5=1+4

5=2+3

算法一用回溯法来实现

针对所给问题,定义问题的解空间;如本题对5的拆分来说,1<=拆分的数<=5。确定易于搜索的解空间结构;如本题对5的拆分来说,用x[]数组来存储解,每个数组元素的取值范围都是1<=拆分的数<=5,从1开始搜索直到5。搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。如本题对5的拆分来说,为了避免重复,x>=x[j](i>j),如x[]={2,3}满足条件而x[]={3,2}就不满足条件不是可行解即无效。

#include

#include

void splitN(int n,int m);//n是需要拆分的数,m是拆分的进度。

int x[1024]={0},total=0 ;//total用于计数拆分的方法数,x[]用于存储解

void main()

{

int n ;

printf("please input the natural number n:");

scanf("%d",&n);

splitN(n,1);

printf("There are %d ways to split natural number %d. ",total,n);

}

void splitN(int n,int m)

{//n是需要拆分的数,m是拆分的进度

int rest,i,j;

for(i=1;i<=n;i++)

{//从1开始尝试拆分

if(i>=x[m-1])

{//拆分的数大于或等于前一个从而保证不重复

x[m]=i ;//将这个数计入结果中

rest=n-i ;//剩下的数是n-i,如果已经没有剩下的了,并且进度(总的拆分个数)大于

1,说明已经得到一个结果了

if(rest==0&&m>1)

{

total++;

printf("%d\t",total);

for(j=1;j

{

printf("%d+",x[j]);

}

printf("%d ",x[m]);

printf("\n");

}

else

{

splitN(rest,m+1);//否则将剩下的数进行进度为m+1拆分

}

x[m]=0;//取消本次结果,进行下一次拆分。环境恢复,即回溯 }

}

}

算法二用递归来实现

任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和,试求n的所有拆分。

用不完全归纳法

n =2 可拆分成2 =1 +1

n =3 可拆分成3 =1 +2 =1 +1 +1

n =4 可拆分成4 =1 +3 =1 +1 +2 =1 +1 +1 +1 =2 +2

……

n =7 可拆分成7 =1 +6

=1 +1 +5

=1 +1 +1 +4

=1 +1 +1 +1 +3

=1 +1 +1 +1 +1 +2

=1 +1 +1 +1 +1+1+1

=1 +1 +1 +2 +2

=1 +1 +2 +3

=1 +2 +4

=1 +2 +2 +2

=1 +3 +3

=2 +5

=2 +2 +3

=3 +4

用数组a 存储完成n 的一种拆分。从上面不完全归纳法的分析n =7 时,按a[1]分类,有a[1]=1,a[1]= 2,…,a[1]= n/2,共n/2 大类拆分。在每一类拆分时,a[1]= i ,a[2]= n - i ,从k=2,继续拆分从a[k]开始,a[k]能否再拆分取决于a[k]/2 是否大于等于a[k-1]。递归过程的参数t 指向要拆分的数a[k]

#include

using namespace std;

int a[100]={0};

void Split(int t)

{

int i;

for(i = 1; i

{

cout<< a[i]<<"+";

}

cout<

int j = t;

int L = a[j];

for(i = a[j-1]; i <= L/2; i++)

{

a[j] = i;

a[j+1] = L - i;

Split(j+1);

}

}

void SplitNum(int n)

{

int i;

for(i = 1; i <= n/2; i++) {

a[1] = i;

a[2] = n - i;

Split(2);

}

}

int main()

{

int n;

scanf("%d",&n);

SplitNum(n);

return 0;

}

相关文档
最新文档