C语言实现整数划分问题
2014-04-21 21:51
405 查看
参照点击打开链接
1、题目描述:输入一个正数n,输出所有和为n连续正数序列。
例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3个连续序列1-5、4-6和7-8。
思路:
等差数列是常见数列的一种,如果一个数列从第二项起,每一项与它的前一项的差等于同一个常数,这个数列就叫做等差数列,而这个常数叫做等差数列的公差,公差常用字母d表示。例如:1,3,5,7,9……1+2(n-1)。等差数列的通项公式为:an=a1+(n-1)d
(1)前n项和公式为:或Sn=n(a1+an)/2=[a1+a1+(n-1)d]* n/2=a1 n+ n (n-1)d /2.。注意: 以上n均属于正整数。
本题中已知Sn=n, 公比d =1,首项末项都不知道。为了方便得知首项,将遍历临时变量取值。
算法设计与分析 王晓东 p22
2、整数划分问题
将正整数n表示成一系列正整数之和,n=n1+n2+…+nk,其中n1>=n2>=…>=nk>=1,k>=1。
正整数n的这种表示称为正整数n的划分。正整数n的不同的划分个数称为正整数n的划分数,记作p(n)。
例如正整数6有如下11种不同的划分,所以p(6)=11。
6;
5+1;
4+2,4+1+1;
3+3,3+2+1,3+1+1+1;
2+2+2,2+2+1+1,2+1+1+1+1;
1+1+1+1+1+1.
思路:
注意6=1+5 和 6=5+1被认为是同一个划分。在正整数n所有不同的划分中,将最大加数n1不大于m的划分个数记作f(n,m),称它为属于n的一个m划分
该问题是求出n的所有划分个数,即f(n, n)。下面我们考虑求f(n,m)的方法;
根据n和m的关系,考虑以下几种情况:
(1)当n=1时,不论m的值为多少(m>0),只有一种划分即{1};
(2) 当m=1时,不论n的值为多少,只有一种划分即n个1,{1,1,1,...,1};
(3) 当n=m时,根据划分中是否包含n,可以分为两种情况:
(a). 划分中包含n的情况,只有一个即{n};
(b). 划分中不包含n的情况,这时划分中最大的数字也一定比n小,即n的所有(n-1)划分。
因此 f(n,n) =1 + f(n,n-1);
(4) 当n<m时,由于划分中不可能出现负数,因此就相当于f(n,n);
(5) 但n>m时,根据划分中是否包含最大值m,可以分为两种情况:
(a). 划分中包含m的情况,即{m, {x1,x2,...xi}}, 其中{x1,x2,... xi} 的和为n-m,可能再次出现m,因此是(n-m)的m划分,因此这种划分
个数为f(n-m, m);
(b). 划分中不包含m的情况,则划分中所有值都比m小,即n的(m-1)划分,个数为f(n,m-1);
因此 f(n, m) = f(n-m, m)+f(n,m-1);
综合以上情况,我们可以看出,上面的结论具有递归定义特征,其中(1)和(2)属于回归条件,(3)和(4)属于特殊情况,将会转换为情况(5)。而情况(5)为通用情况,属于递推的方法,其本质主要是通过减小m以达到回归条件,从而解决问题。其递推表达式如下:
f(n, m)= 1; (n=1 or m=1)
f(n, n); (n<m)
1+ f(n, m-1); (n=m)
f(n-m,m)+f(n,m-1); (n>m)
1、题目描述:输入一个正数n,输出所有和为n连续正数序列。
例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3个连续序列1-5、4-6和7-8。
思路:
等差数列是常见数列的一种,如果一个数列从第二项起,每一项与它的前一项的差等于同一个常数,这个数列就叫做等差数列,而这个常数叫做等差数列的公差,公差常用字母d表示。例如:1,3,5,7,9……1+2(n-1)。等差数列的通项公式为:an=a1+(n-1)d
(1)前n项和公式为:或Sn=n(a1+an)/2=[a1+a1+(n-1)d]* n/2=a1 n+ n (n-1)d /2.。注意: 以上n均属于正整数。
本题中已知Sn=n, 公比d =1,首项末项都不知道。为了方便得知首项,将遍历临时变量取值。
int sumNBySequence(int Sn) { int a1,an,temp,n; for(n = 2; n*n <= 2*Sn; n++ )//等差公式 n(2a1+(n-1)*d)= 2Sn。其中d = 1。n首先是2Sn的因子 { temp = 2*Sn -n*n+n;//等差公式变形为:2na1+n*n-n = 2Sn if(temp%(2*n) == 0) { a1 = temp/(2*n); an = a1+ n-1; printf("%d,%d",a1,an); } printf("\n"); //空行表示该n求不得a1和an } return 0; } int main () { sumNBySequence(30000); return 0; }
算法设计与分析 王晓东 p22
2、整数划分问题
将正整数n表示成一系列正整数之和,n=n1+n2+…+nk,其中n1>=n2>=…>=nk>=1,k>=1。
正整数n的这种表示称为正整数n的划分。正整数n的不同的划分个数称为正整数n的划分数,记作p(n)。
例如正整数6有如下11种不同的划分,所以p(6)=11。
6;
5+1;
4+2,4+1+1;
3+3,3+2+1,3+1+1+1;
2+2+2,2+2+1+1,2+1+1+1+1;
1+1+1+1+1+1.
思路:
注意6=1+5 和 6=5+1被认为是同一个划分。在正整数n所有不同的划分中,将最大加数n1不大于m的划分个数记作f(n,m),称它为属于n的一个m划分
该问题是求出n的所有划分个数,即f(n, n)。下面我们考虑求f(n,m)的方法;
根据n和m的关系,考虑以下几种情况:
(1)当n=1时,不论m的值为多少(m>0),只有一种划分即{1};
(2) 当m=1时,不论n的值为多少,只有一种划分即n个1,{1,1,1,...,1};
(3) 当n=m时,根据划分中是否包含n,可以分为两种情况:
(a). 划分中包含n的情况,只有一个即{n};
(b). 划分中不包含n的情况,这时划分中最大的数字也一定比n小,即n的所有(n-1)划分。
因此 f(n,n) =1 + f(n,n-1);
(4) 当n<m时,由于划分中不可能出现负数,因此就相当于f(n,n);
(5) 但n>m时,根据划分中是否包含最大值m,可以分为两种情况:
(a). 划分中包含m的情况,即{m, {x1,x2,...xi}}, 其中{x1,x2,... xi} 的和为n-m,可能再次出现m,因此是(n-m)的m划分,因此这种划分
个数为f(n-m, m);
(b). 划分中不包含m的情况,则划分中所有值都比m小,即n的(m-1)划分,个数为f(n,m-1);
因此 f(n, m) = f(n-m, m)+f(n,m-1);
综合以上情况,我们可以看出,上面的结论具有递归定义特征,其中(1)和(2)属于回归条件,(3)和(4)属于特殊情况,将会转换为情况(5)。而情况(5)为通用情况,属于递推的方法,其本质主要是通过减小m以达到回归条件,从而解决问题。其递推表达式如下:
f(n, m)= 1; (n=1 or m=1)
f(n, n); (n<m)
1+ f(n, m-1); (n=m)
f(n-m,m)+f(n,m-1); (n>m)
int Part(int n, int m) { if ((n < 1)||(m < 1)) return 0; if ((n == 1)||(m == 1)) return 1; if (n < m) return Part(n, n); if (n == m) return Part(n, m-1) + 1; return Part(n, m-1) + Part(n-m, m); } int main () { Part(6,6); }
相关文章推荐
- 整数划分问题的递归算法-c语言
- 算法实现(4)整数划分问题
- (C语言)整数划分问题 递归和递推
- 整数划分问题的递归算法-c语言
- 整数划分问题(C语言求解)
- 整数划分(C语言实现)
- 整数划分问题算法分析与实现(递归)
- C语言整数类型及printf格式化输出问题总结复习及进制转换的简单实现
- C#实现整数划分问题——带输出
- 整数划分问题--c语言
- 整数划分问题java实现
- 整数划分问题的递归算法-c语言
- C语言之整数划分问题(递归法)实例代码
- 【C语言】【笔试题】实现一个函数int my_atoi(char s[]),可以将一个字符串转换为对应的整数。
- 整数划分问题 水题喽
- 整数划分问题解法2-动态规划
- 整数划分问题
- 整数划分问题 hdu 1028(母函数)
- 整数的划分问题
- 整数划分部分问题和算法