C语言实现整数划分问题

来源:互联网 发布:检测网络的命令ping 编辑:程序博客网 时间:2024/06/06 03:10

参照点击打开链接

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>=1k>=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);     }



0 1
原创粉丝点击