整数划分-张义胜

来源:互联网 发布:淘宝有招脚模的吗 编辑:程序博客网 时间:2024/06/05 11:19

一、问题描述

将整数n表示成一系列整数之和,n=n1+n2+...+nk      (其中n1>n2>....>nk

正整数n的这种表示称为正整数n的划分,例如正整数6:

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的划分,我们采用递归的方式

首先div(n,m)表示将n的所有划分的最大加数不超过m的一系列加数之和的个数,我们可建立如下递归关系:

(1)div(n,1)=1;//最大加不超过1的只有一种划分

(2)div(n,m)=div(n,m-1)+div(n-m,m);n>m>1;

(3)div(n,m)=div(n,n),n<=m;

(4)div(n,n)=1+div(n,n-1);

说明:div(n-m,m)表示将n表示成最大加数为m的一系列加数之和,或许有人就不明白为什么会是div(n-m,m)。

我在这里解释一下,div(n,m)=div(n,m-1)+div(m-1,m);也就是说div(m-1,m)是把m表示成一系列加数之和且加数中一定包含m的个数。要把n表示为一系列加数之和,其中包含m,则n可表示为(n-m)+m,我们在把n-m拆开,把它表示为一系列加数之和,即n-m还可怎样划分,得div(m-1,m)。

三、源码

int div(int n,int m)//n和m分别表示待划分的数与最大加数不超过m

{

    if(n==m&&n==1)

   {

       return 1;   //m=n=1时只有一种划分,返回一

   }

   if(n<1||m<1)

   {

      return 0;//n小于1或m小于1时,为0

   }

   else

   {

     if(n<m)

       {

             return div(n,n);//如果m>n且大于1时,返回div(n,n)

       }

     if(n==m)

      {

            return 1+div(n,n-1);//当m=n且大于1时

      }

     else

     {

          return div(n,m-1)+div(n-m,m);//n>m且大于1

     }

   }

}

//第一次发文,不喜勿喷,如有不当之处,请大神指教
1 1
原创粉丝点击