您的位置:首页 > 其它

自然数的拆分

2015-08-21 18:09 274 查看
【问题描述】自然数的拆分:任何一个大于1的自然数N,
总可以拆分成若干个自然数之和,并且有多种拆分方法。试求 n的所有拆分。
例如自然数5,可以有如下一些拆分方法:
5=1+1+1+1+1
5=1+1+1+2
5=1+2+2
5=1+4
5=2+3

注意,本题中N拆分出来的数x的范围是1<=x<N。假如x可以等于N,那么本题和整数划分是一个道理。现在,这里与整数划分这个题的答案只少1,即N拆分成N本身的情况。

整数划分可以参考:
http://www.cnblogs.com/hoodlum1980/archive/2008/10/11/1308493.html http://blog.csdn.net/sunquana/article/details/9245443
算法一 用回溯法来实现

针对所给问题,定义问题的解空间;如本题对5的拆分来说,1<=拆分的数<5。

确定用于搜索的解空间结构;如本题对5的拆分来说,用x[ ]数组来存储解,每个数组元素的取值范围都是1<=拆分的数<=5,从1开始搜索直到5。

搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。

如本题对5的拆分来说,为了避免重复,x[i] >= x[j] ( i > j ),如x[]={2,3}满足条件而x[]={3,2}就不满足条件不是可行解即无效。

#include <stdio.h>
#include <stdlib.h>

int a[100]={0};
void Split(int t)
{
int i,j,L;
for(i = 1; i <t; i++)
{
printf("%d+",a[i]);
}
printf("%d\n",a[i]);

j = t;
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;
}


View Code

参考:http://wenku.baidu.com/link?url=H7tDqvEmnds9SN4FfuwMw8M6AfAMUl44-vCR83Z4LKv9UN-HAU159GJtFR5M48t11XBJFMwP3i4qPk6u2WHEORZDeYhraBQt63zvaDUNSAi
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: