整数划分问题
小学奥数知识点趣味学习——整数的分拆

小学奥数知识点趣味学习——整数的分拆整数的拆分,就是把一个自然数表示成为若干个自然数的和的形式,每一种表示方法,就是自然数的一个分拆。
整数的分拆是古老而又有趣的问题,其中最著名的是哥德巴赫猜想。
在国内外数学竞赛中,整数分拆的问题常常以各种形式出现,如,存在性问题、计数问题、最优化问题等。
例1.电视台要播放一部30集电视连续剧,若要求每天安排播出的集数互不相等,则该电视连续剧最多可以播几天?分析与解:由于希望播出的天数尽可能地多,所以,在每天播出的集数互不相等的条件下,每天播放的集数应尽可能地少。
我们知道,1+2+3+4+5+6+7=28。
如果各天播出的集数分别为1,2,3,4,5,6,7时,那么七天共可播出28集,还剩2集未播出。
由于已有过一天播出2集的情形,因此,这余下的2集不能再单独于一天播出,而只好把它们分到以前的日子,通过改动某一天或某二天播出的集数,来解决这个问题。
例如,各天播出的集数安排为1,2,3,4,5,7,8或1,2,3,4,5,6,9都可以。
所以最多可以播7天。
例2:有面值为1分、2分、5分的硬币各4枚,用它们去支付2角3分。
问:有多少种不同支付方法?分析与解:要付2角3分钱,最多只能使用4枚5分币。
因为全部1分和2分币都用上时,共值12分,所以最少要用3枚5分币。
当使用3枚5分币时,5×3=15,23-15=8,所以使用2分币最多4枚,最少2枚,可有23=15+(2+2+2+2),23=15+(2+2+2+1+1),23=15+(2+2+1+1+1+1),共3种支付方法。
当使用4枚5分币时,5×4=20,23-20=3,所以最多使用1枚2分币,或不使用,从而可有23=20+(2+1),23=20+(1+1+1),共2种支付方法。
总共有5种不同的支付方法。
例3:把37拆成若干个不同的质数之和,有多少种不同的拆法?将每一种拆法中所拆出的那些质数相乘,得到的乘积中,哪个最小?解:37=3+5+29=2+5+7+23=3+11+23=2+3+13+19=5+13+19=7+11+19=2+5+11+19=7+13+17=2+5+13+17=2+7+11+17,共10种不同拆法,其中3×5×29=435最小。
数学中的整数分拆

数学中的整数分拆在数学中,整数分拆是一个有趣且重要的概念。
它涉及到将一个正整数拆分成若干个正整数之和的过程。
整数分拆在代数、组合数学以及数论等领域都有广泛的应用和研究。
本文将介绍整数分拆的基本概念、应用以及一些有趣的性质。
一、基本概念整数分拆即是将一个正整数拆分成若干个正整数之和的过程。
例如,对于整数4,可以将其分拆为1+1+1+1、2+2、1+1+2等不同的方式。
整数分拆的方式可以具有不同的顺序,但只要拆分的数目相同,就属于同一种拆分方式。
通常,我们用P(n)表示一个正整数n的拆分数,P(n)的值表示n的所有拆分方式的总数。
二、应用整数分拆在实际问题中有着广泛的应用。
下面以组合数学为例,介绍一些具体的应用场景。
1. 钱币组合问题假设有不同面额的硬币,例如1元、2元、5元等,我们需要凑出一个特定金额的零钱。
这个问题可以转化为整数分拆的问题。
例如,我们要凑齐10元,可以分解为1+1+1+1+1+1+1+1+1+1、1+1+1+1+1+1+1+1+2、1+1+1+1+1+1+1+2+2等多种方式。
2. 整数拆分问题整数拆分问题是指将一个正整数拆分成若干个正整数之和,并且这些正整数之间没有顺序要求的问题。
例如,将整数4拆分成1+1+1+1、1+1+2、1+3、2+2等都属于整数拆分的方式。
整数拆分问题在计算机科学中有着广泛的应用,例如动态规划算法中的背包问题、分割问题等。
三、性质整数分拆具有很多有趣的性质,下面介绍其中的一些。
1. 奇偶性对于正整数n,其拆分数P(n)具有一定的奇偶性规律。
当n为奇数时,P(n)为奇数;当n为偶数时,P(n)为偶数。
这个结论可以通过归纳法证明。
2. 递推关系正整数n的拆分数P(n)可以通过递推关系计算得到。
具体地,对于正整数m,其拆分数可以通过计算m-1的拆分数、m-2的拆分数等递推得到。
例如,P(5)可以通过计算P(4)、P(3)、P(2)、P(1)的值得到。
3. 生成函数生成函数是一种用于研究组合数学问题的工具。
整数的分类与运算

整数的分类与运算整数是数学中的一种基本数集,它包含了正整数、负整数和零。
在数学运算中,整数具有特定的分类和运算规则。
本文将详细讨论整数的分类与运算,并按照合适的格式进行阐述。
一、整数的分类整数可以分为以下几类:正整数、负整数和零。
1. 正整数:正整数是大于零的整数,用正号表示。
例如,1、2、3等都属于正整数。
2. 负整数:负整数是小于零的整数,用负号表示。
例如,-1、-2、-3等都属于负整数。
3. 零:零表示没有数量的概念,整数中唯一的一个既不属于正整数又不属于负整数的数。
用0表示。
二、整数的运算整数的运算包括加减乘除四则运算和取模运算。
1. 加法运算:整数之间的加法运算可以简单地进行数值相加,符号按照以下规则确定:- 两个正整数相加,结果仍为正整数;- 两个负整数相加,结果仍为负整数;- 正整数和负整数相加,结果的符号由绝对值大的整数决定,绝对值大的整数决定结果的正负;- 加法运算还满足交换律和结合律。
2. 减法运算:整数之间的减法运算可以简单地进行数值相减,符号按照以下规则确定:- 一个整数减去另一个整数,可以转化为加法运算,即加上被减整数的相反数;- 减法运算还满足减法法则,即减数加上差等于被减数。
3. 乘法运算:整数之间的乘法运算结果仍为整数,符号按照以下规则确定:- 两个正整数相乘,结果仍为正整数;- 两个负整数相乘,结果仍为正整数;- 一个正整数和一个负整数相乘,结果仍为负整数;- 乘法运算还满足交换律和结合律。
4. 除法运算:整数之间的除法运算可能会产生小数和余数,符号按照以下规则确定:- 两个正整数相除,结果可以为正整数、小数或分数;- 两个负整数相除,结果可以为正整数、小数或分数;- 正整数除以负整数,结果可以为正整数、小数或分数;- 负整数除以正整数,结果可以为正整数、小数或分数;- 除法运算满足除法法则。
5. 取模运算:整数除法中的取模运算是指在整数除法中求得的余数。
取模运算可以用符号“%”表示。
小学奥数知识点趣味学习——整数的分拆

小学奥数知识点趣味学习——整数的分拆整数分拆内容概述:1.一般的有,把一个整数表示成两个数相加,当两个数相近或相等的时候,乘积最大。
也就是把整数分拆成两个相等或者相差1的两个整数。
2.一般的有,把自然数m分成n个自然数的和,使其乘积最大,则先把m进行对n的带余除法,表示成m=np+r,则分成r个(p+1),(n-r)个P。
3.把自然数S (S>1)分拆为若干个自然数的和(没有给定是几个),则分开的数当中最多有两个2,其他的都是3,这样它们的乘积最大。
4.把自然数分成若干个互不相等的整数,则先把它表示成2+3+4+5+…+n形式,当和等于原数则可以,若不然,比原数大多少除去等于它们差的那个自然数。
如果仅大于1,则除去2,再把最大的那个数加1。
5.若自然数N有k个大于1的奇约数,则N共有k种表示为两个或两个以上连续自然数之和的方法。
即当有m个奇约数表示的乘积,则有奇约数个奇约数。
6.共轭分拆.我们通过下面一个例子来说明共轭分拆:如:10=4+2+2+1+1,我们画出示意图,我们将其翻转(将图左上到右下的对角线翻转即得到):,可以对应的写成5+3+l+1,也是等于10,即是10的另一种分拆方式。
我们把这两种有关联的分拆方式称为互为共轭分拆。
典型例题:1.写出13=1+3+4+5的共轭分拆。
【分析与解】画出示意图,翻转得到,对应写为4+3+3+2+1=13,即为13=1+3+4+5的共轭分拆。
2.电视台要播出一部30集电视连续剧,若要每天安排播出的集数互不相等。
则该电视连续剧最多可以播出几天?【分析与解】由于希望播出的天数尽可能地多,若要满足每天播出的集数互不相等的条件下,每天播出的集数应尽可能地少。
选择从1开始若干连续整数的和与30最接近(小于30)的情况为1+2+3+4+5+6+7=28,现在就可以播出7天,还剩下2集,由于已经有2集这种情况,就是把2集分配到7天当中又没有引起与其他的几天里播出的集数相同.于是只能选择从后加.即把30表示成:30=1+2+3+4+5+6+9或30=1+2+3+4+5+7+8即最多可以播出7天。
实验一 整数划分问题

实验一 整数划分问题一、问题描述将正整数n 表示成一系列正整数之和,k n n n n +++= 21,其中.1,121>=>=>=>=>=k n n n k 正整数n 的这种表示称为正整数n 的划分。
正整数n 的不同的划分个数称为正整数n 的划分数,记作)(n p 。
例如正整数6有如下11种不同的划分,所以)6(p =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.二、问题分析如果设)(n p 为正整数n 的划分数,则难以找到递归关系,因此考虑增加一个自变量:将最大加数1n 不大于m 的划分个数记作),(m n q 。
根据n 和m 的关系,考虑以下几种情况:(1)当1=n 时,不论m 的值为多少)0(>m ,只有一种划分即{}1;(2)当1=m 时,不论n 的值为多少,只有一种划分即n 个1,{}1,1,1,1 ;(3)当m n =时,根据划分中是否包含n ,可以分为两种情况:(a )划分中包含n 的情况,只有一个即{}n ;(b )划分中不包含n 的情况,这时划分中最大的数字也一定比n 小,即n 的所有)1(-n 划分。
因此, )1,(1),(-+=n n q n n q ;(4)当m n <时,由于划分中不可能出现负数,因此就相当于),(n n q ;(5)但m n >时,根据划分中是否包含最大值m ,可以分为两种情况: (a )划分中包含m 的情况,即{}{}i x x x m ,,,,21 , 其中{}i x x x ,,,21 的和为m n -,可能再次出现m ,因此是m n -的m 划分,因此这种划分个数为),(m m n q -;(b )划分中不包含m 的情况,则划分中所有值都比m 小,即n 的1-m 划分,个数为)1,(-m n q ;因此)1,(),(),(-+-=m n q m m n q m n q ;综合以上情况,我们可以看出,上面的结论具有递归定义特征,其中(1)和(2)属于边界条件,(3)和(4)属于特殊情况,将会转换为情况(5)。
贝蒂瑞利定理整数划分

贝蒂瑞利定理整数划分全文共四篇示例,供读者参考第一篇示例:贝蒂瑞利定理是数学中一个非常重要的定理,它关于整数划分的性质给出了重要的结论。
整数划分是一个古老而重要的数论问题,它研究如何将一个正整数表示为一系列正整数之和的形式。
在整数划分中,我们通常会遇到一些有趣的问题和挑战,而贝蒂瑞利定理的提出正是为了解决整数划分中的一些问题。
整数划分问题最早可以追溯到欧几里得时代,当时欧几里得就曾对整数划分进行了研究。
整数划分问题的研究并没有停留在欧几里得时代,而是一直延续至今。
贝蒂瑞利定理就是在这样一个背景下应运而生的。
贝蒂瑞利定理的表述比较简单,它指出任意一个正整数n可以表示为以下形式的整数划分个数:n = p(1) + p(2) + ... + p(k)其中p(1), p(2), ..., p(k)都是正整数,且满足p(1) ≤ p(2) ≤ ... ≤ p(k)。
换句话说,贝蒂瑞利定理给出了整数划分的一种特殊表示方式。
贝蒂瑞利定理的证明并不难,主要是通过对整数划分的性质进行分析和推导。
在证明过程中,我们需要借助一些数论的基本知识,例如贝努利数的性质、斯特林数的性质等。
通过这些基本知识,我们可以比较容易地证明贝蒂瑞利定理的正确性。
贝蒂瑞利定理在数论中有着广泛的应用,特别是在组合数学和数论分析领域。
通过贝蒂瑞利定理,我们可以更好地理解整数划分的性质和规律,从而解决一些相关的数学问题。
贝蒂瑞利定理还可以用来推导一些数学恒等式,为数学研究提供重要的参考。
第二篇示例:贝蒂瑞利定理,又称为整数划分定理,是分析数论中一个重要的定理,它探讨了整数划分的问题。
整数划分是指将一个正整数n表示为一系列整数之和的过程。
整数4可以划分为1+1+1+1、2+1+1和2+2这几种分法。
整数划分在数学领域有着广泛的应用,涵盖了许多重要领域,如组合数学、代数、数论等。
贝蒂瑞利定理的内容比较复杂,但其基本思想是:一个正整数n的整数划分种数,等于n的分解中最大加数不超过m的整数划分种数的总和,其中m为正整数。
整数划分问题c语言编程

整数划分问题问题:将以正整数n 表示成一系列正整数之和表示成一系列正整数之和.n=n1+n2+n3+...+nk (.n=n1+n2+n3+...+nk (.n=n1+n2+n3+...+nk (其中其中n1>=n2>=n3>=nk>=1, k>=1)n1>=n2>=n3>=nk>=1, k>=1)这就是正整数这就是正整数n 的一个划分,正整数n 不同的划分个数称为正整数n 的划分数的划分数, , , 记作记作p(n)分析:在正整数n 的所有不同的划分中的所有不同的划分中,,将最大加数n1不大于m 的的划分个数记为q(n,m),q(n,m),可以建立如下递归关系可以建立如下递归关系可以建立如下递归关系1、 q(n,1)=1,n>=1;当最大加数n1不大于1的时候,任何正整数只有一种划分,即n=1+1+1+n=1+1+1+……+1+1,,其中有n 个12、 q(n,m)=q(n,n),m>=n;最大加数n1实际上不能大于n 。
特殊的,。
特殊的, q(1,m)=1 q(1,m)=13、 q(n,n)=1+q(n,n-1)q(n,n)=1+q(n,n-1);;正整数n 的划分由n1=n 的一种还有最大划分小于等于n-1的划分组成的划分组成4、 q(n,m)=q(n,m-1)+q(n-m,m),n>m>1q(n,m)=q(n,m-1)+q(n-m,m),n>m>1;;正整数n 的最大加数n1不大于m 的划分由n1=m 的划分和n1<=m-1的划分组成的划分组成递归式为递归式为: : 1;(n=1 or m=1)q(n, n);(n<m) q (n, m)=q(n, m)= 1+ q(n, n-1);(n=m) q(n,m-1)+q(n-m,m);(n>m) 伪代码伪代码: :q(n,m)/* q(n,m)/*求解整数求解整数n 的划分数的划分数*/ */{ if(n<1||m<1) return 0; 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); } 的具体划分伪代码整数n的具体划分伪代码start: input:n part: { int i,j; for(i=x;i>=1;i--) if(i+total<=n) { a[t++]=i; total+=i; goto part; } if(total==n) print: { count++; print(n=a[0]+a[1]+...+a[t-1]) if (a[k]中,中,k != t-1) print("+"); else print(" "); if(a[1]==a[2]==a[3]==...a[t-1]==1) print("\n"); } } t=t-1 total=total-a[t]; } 程序代码如下:程序代码如下:#include "stdio.h" #define N 100 int a[N]; int t=0;//t作为数组a[]的下标的下标int total=0; int count=0;//划分数的计数器划分数的计数器划分数的计数器void part(int x,int n) { int i,j; for(i=x;i>=1;i--) if(i+total<=n) { a[t++]=i; //将n 的划分由大到小给数组a[] total+=i;//total 的值逐渐向n 靠拢,当n==total 时就是打印的时候时就是打印的时候 part(i,n); //递归调用,直到满足n==total } if(total==n)//等式两边n=total 时打印时打印{ count++; //计数,每打印一次增1,最终结果即为划分数,最终结果即为划分数printf("%d=",n);//打印等式左边的n 及= for(j=0;j<t;j++) { printf("%d",a[j]);//依次输出a[0],a[1],a[2]..... if(j<t-1) printf("+");//如果如果a[j]不是最后一个加数,那么打印+号 else { if(a[1]==1||a[0]==n) if(a[1]==1||a[0]==n) printf("\n");//printf("\n");//唯有n=n 或者a[1]为1,即除a[0]以外都为1的情况,进行下一行输出的情况,进行下一行输出else printf(" ");//同行等式间分割号同行等式间分割号} } } t--;//回到上一步t 值total-=a[t];//回到上一步total 值} void main() { int n; printf("输入是n:"); scanf("%d",&n); part(n,n);// 将n 划分成若干正整数之和的划分数。
整数划分问题

(2) dp[n][m]= dp[n][m+1]+ dp[n-m][m]dp[n][m]表示整数n 的划分中,每个数不小于m 的划分数。
B 划分的多个正整数中,正整数的数量是固定的把一个整数n 无序划分成k 份互不相同的正整数之和的方法总数。
方程为:dp[n][k]= dp[n-k][k]+ dp[n-1][k-1];证明方法参考:/program/html/0369.htm另一种理解,总方法可以分为两类:第一类: n 份中不包含1 的分法,为保证每份都>= 2,可以先拿出k 个1 分到每一份,然后再把剩下的n- k 分成k 份即可,分法有: dp[n-k][k]第二类: n 份中至少有一份为1 的分法,可以先那出一个1 作为单独的1份,剩下的n- 1 再分成k- 1 份即可,分法有:dp[n-1][k-1]相关习题:/ojs/show.php?Proid=1402&Contestid=0:8080/online/?action=problem&type=show&id=11299&courseid=0 #include<iostream>#include<stdio.h>using namespace std;int dp[4505][4505];int solve(int n,int m){int i,j;for(i=1;i<=n;++i){dp[i][0]=0;for(j=1;j<=m;++j){dp[0][j]=0;if(i>=j)dp[i][j]=dp[j-1][j]+1;else{dp[i][j]=dp[i-1][j]+dp[i][j-i];if(dp[i][j]>=1000000007)dp[i][j]-=1000000007;}}}return dp[n][m];}int main(){int n,m;scanf("%d %d",&n,&m);printf("%d\n",solve(n,m));return 0;}类似问题:M个小球装N个盒子,或者苹果装盘问题把M个球放到N个盒子,允许有空的盒子(不放球),有多少种放法?典型的DP问题:用F(m,n)表示有多少种放法:如果m=0 或者m=1 , F = 1如果n=0 或者n=1 , F =1既F(0,0) = F(0,1) = F(1,0) = F(1,1) = 1否则F = F(m-n,n) + F(m,n-1)这就是DP的解空间递归解每一次DP应用,都是一次创造#include <stdio.h>int F(int m,int n);int main(){int m;int n;int f;printf("Intput the number of M and N \n");scanf("%d %d",&m,&n);f = F(m,n);printf("There are total %d methods\n\n",f);};int F(int m,int n){if(m==0||m==1) return 1;if(n==0||n==1) return 1;if(m<n) return F(m,m);else return F(m-n,n)+F(m,n-1);};三、关于整数的质因子和分解【问题描述】歌德巴赫猜想说任何一个不小于6的偶数都可以分解为两个奇素数之和。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
整数划分问题整数划分是一个经典的问题。
希望这道题会对你的组合数学的解题能力有所帮助。
Input每组输入是两个整数n和k。
(1 <= n <= 50, 1 <= k <= n)Output对于每组输入,请输出六行。
第一行:将n划分成若干正整数之和的划分数。
第二行:将n划分成k个正整数之和的划分数。
第三行:将n划分成最大数不超过k的划分数。
第四行:将n划分成若干奇正整数之和的划分数。
第五行:将n划分成若干不同整数之和的划分数。
第六行:打印一个空行。
Sample Input5 2Sample Output72333Hint:1、将5划分成若干正整数之和的划分为:5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+12、将5划分成2个正整数之和的划分为:3+2, 4+13、将5划分成最大数不超过2的划分为:1+1+1+1+1, 1+1+1+2, 1+2+24、将5划分成若干奇正整数之和的划分为:5, 1+1+3, 1+1+1+1+15、将5划分成若干不同整数之和的划分为:5, 1+4, 2+3来源:/ojs/show.php?Proid=1402&Contestid=0最新评论发表评论您尚未登陆本站,不能发表评论,请登陆else{min=n-(int)(n/k)*(k-1);for(i=min;(i<=n-k+1&&i<=max);i++){counter+=Func_b(n-i,k-1,i);}return counter;}}int Func_c(int n,int max) //将n划分成若干奇正整数之和的划分数。
{int counter=0;int i;if(max<=1){return 1;}else{for(i=1;2*i<=max+1;i++){counter+=Func_c(n-2*i+1,(i<n-2*i+1)?i:(n-2*i+1));}}int Func_d(int n,int max) // 将n划分成若干不同整数之和的划分数。
{int counter=0;int i;if(max*(max-1)/2<n){return 0;}else{if(max*(max-1)/2==n||n==0){return 1;}else{for(i=1;i<max;i++){counter+=Func_d(n-i,i);}return counter;}}}return 1;}else{for(i=1;i<=max;i++){counter+=Func_a(n-i,(i<n-i)?i:(n-i));}return counter;}}int Func_b(int n,int k,int max) //将n划分成k个不大于max的正整数之和的划分数。
{int counter=0;int min,i;min=(int)((n+k-1)/k);if(k==1||k==n){return 1;}else{min=n-(int)(n/k)*(k-1);for(i=min;(i<=n-k+1&&i<=max);i++){}return counter;}}int Func_c(int n,int max) //将n划分成若干奇正整数之和的划分数。
{int counter=0;int i;if(max<=1){return 1;}else{for(i=1;2*i<=max+1;i++){counter+=Func_c(n-2*i+1,(i<n-2*i+1)?i:(n-2*i+1));}return counter;}}int Func_d(int n,int max) // 将n划分成若干不同整数之和的划分数。
int counter=0;int i;if(max*(max-1)/2<n){return 0;}else{if(max*(max-1)/2==n||n==0){return 1;}else{for(i=1;i<max;i++){counter+=Func_d(n-i,i);}return counter;}}}void main(){int n,k;cout<<"输入是两个整数n和k。
(1 <= n <= 50, 1 <= k <= n)\n";cin>>n>>k;cout<<Func_a(n,n)<<endl;//第一行:将n划分成若干正整数之和的划分数。
return counter;}}int Func_b(int n,int k,int max) //将n划分成k个不大于max的正整数之和的划分数。
{int counter=0;int min,i;min=(int)((n+k-1)/k);if(k==1||k==n){return 1;}else{min=n-(int)(n/k)*(k-1);for(i=min;(i<=n-k+1&&i<=max);i++){counter+=Func_b(n-i,k-1,i);}return counter;}}int Func_c(int n,int max) //将n划分成若干奇正整数之和的划分数。
int counter=0;int i;if(max<=1){return 1;}else{for(i=1;2*i<=max+1;i++){counter+=Func_c(n-2*i+1,(i<n-2*i+1)?i:(n-2*i+1));}return counter;}}int Func_d(int n,int max) // 将n划分成若干不同整数之和的划分数。
{int counter=0;int i;if(max*(max-1)/2<n){return 0;}else{if(max*(max-1)/2==n||n==0){return 1;}else{for(i=1;i<max;i++){counter+=Func_d(n-i,i);}return counter;}}}void main(){int n,k;cout<<"输入是两个整数n和k。
(1 <= n <= 50, 1 <= k <= n)\n";cin>>n>>k;cout<<Func_a(n,n)<<endl;//第一行:将n划分成若干正整数之和的划分数。
cout<<Func_b(n,k,n-k+1)<<endl;//第二行:将n划分成k个正整数之和的划分数。
cout<<Func_a(n,k)<<endl;//第三行:将n划分成最大数不超过k的划分数。
cout<<Func_c(n,n)<<endl;//第四行:将n划分成若干奇正整数之和的划分数。
cout<<Func_d(n,n)<<endl;//第五行:将n划分成若干不同整数之和的划分数。
int min,i;min=(int)((n+k-1)/k);if(k==1||k==n){return 1;}else{min=n-(int)(n/k)*(k-1);for(i=min;(i<=n-k+1&&i<=max);i++){counter+=Func_b(n-i,k-1,i);}return counter;}}int Func_c(int n,int max) //将n划分成若干奇正整数之和的划分数。
{int counter=0;int i;if(max<=1){return 1;}elsefor(i=1;2*i<=max+1;i++){counter+=Func_c(n-2*i+1,(i<n-2*i+1)?i:(n-2*i+1));}return counter;}}int Func_d(int n,int max) // 将n划分成若干不同整数之和的划分数。
{int counter=0;int i;if(max*(max-1)/2<n){return 0;}else{if(max*(max-1)/2==n||n==0){return 1;}else{for(i=1;i<max;i++){counter+=Func_d(n-i,i);}return counter;如6的整数划分为最大数6 65 5 + 14 4 + 2, 4 + 1 + 13 3 + 3, 3 + 2 + 1, 3 + 1 + 1 + 12 2 + 2 + 2, 2 + 2 + 1 + 1, 2 + 1 + 1 + 1 + 11 1 + 1 + 1 + 1 + 1 + 1共11种。
下面介绍一种通过递归方法得到一个正整数的划分数。
递归函数的声明为 int split(int n, int m);其中n为要划分的正整数,m是划分中的最大加数(当m > n时,最大加数为n),1 当n = 1或m = 1时,split的值为1,可根据上例看出,只有一个划分1 或 1 + 1 + 1 + 1 + 1 + 1可用程序表示为if(n == 1 || m == 1) return 1;2 下面看一看m 和 n的关系。
它们有三种关系(1) m > n在整数划分中实际上最大加数不能大于n,因此在这种情况可以等价为split(n, n);可用程序表示为if(m > n) return split(n, n);(2) m = n这种情况可用递归表示为split(n, m - 1) + 1,从以上例子中可以看出,就是最大加数为6和小于6的划分之和用程序表示为if(m == n) return (split(n, m - 1) + 1);(3) m < n这是最一般的情况,在划分的大多数时都是这种情况。
从上例可以看出,设m = 4,那split(6, 4)的值是最大加数小于4划分数和整数2的划分数的和。
因此,split(n, m)可表示为split(n, m - 1) + split(n - m, m)根据以上描述,可得源程序如下:#include <stdio.h>int split(int n, int m){if(n < 1 || m < 1) return 0;if(n == 1 || m == 1) return 1;if(n < m) return split(n, n);if(n == m) return (split(n, m - 1) + 1);if(n > m) return (split(n, m - 1) + split((n - m), m));}int main(){printf("12的划分数: %d", split(12, 12));return 0;}将正整数划分成连续的正整数之和如15可以划分成4种连续整数相加的形式:157 84 5 61 2 3 4 5首先考虑一般的形式,设n为被划分的正整数,x为划分后最小的整数,如果n有一种划分,那么结果就是x,如果有两种划分,就是x和x x + 1,如果有m种划分,就是 x 、x x + 1 、 x x + 1 x + 2 、... 、x x + 1 x + 2 ... x + m - 1将每一个结果相加得到一个公式(i * x + i * (i - 1) / 2) = n,i为当前划分后相加的正整数个数。