拆分自然数的几种算法

温柔似野鬼°
797次浏览
2021年01月27日 23:11
最佳经验
本文由作者推荐

雷锋日活动策划-新学期新打算300字

2021年1月27日发(作者:couplets)
拆分自然数的几种算法

【问题描述】
自然数的拆分:
任何一个大于
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(

);
scanf(

,&n);
splitN(n,1);
printf(

,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(

,total);

for
(j=1;j {
printf(

,x[j]);
}
printf(

,x[m]);




printf(

);
}

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

雷锋日活动策划-新学期新打算300字


雷锋日活动策划-新学期新打算300字


雷锋日活动策划-新学期新打算300字


雷锋日活动策划-新学期新打算300字


雷锋日活动策划-新学期新打算300字


雷锋日活动策划-新学期新打算300字


雷锋日活动策划-新学期新打算300字


雷锋日活动策划-新学期新打算300字