整数划分

将正整数n表示成一系列正整数之和:n=n1+n2+…+nk, 
其中n1≥n2≥…≥nk≥1,k≥1。 
正整数n的这种表示称为正整数n的划分。求正整数n的不 
同划分个数。 
例如正整数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。 


n1为每一式的最大值,将n1作为辅助,这里设m = n1;

这里记n的m划分个数为q(n,m)

针对n,m的各种情况进行讨论;

    if((n<1) || (m<1)) return 0;
    if(n == 1 || m == 1) return 1;//n = 1时,即{1},当m = 1时,即{1,1,1...1}n个1
    if(n == m) return q(n,m-1) + 1;//(1)n = m时,即{n}一个,(2)n的m-1的所有划分个数 (1) + (2) = q(n,m-1) + 1;
    if(n < m) return q(n,n);//实际情况没有这种情况的,所有和上一步相同即n = m 即 q(n,n);
    if(n > m) return q(n,m-1) + q(n-m,m);//(1)当不出现m时,即为n的m-1的所有划分个数,(2)当出现m时,{m,[x1,x2,x3...]},

     其中[x1,x2,x3...]中为n-m个,这里有可能出现m,所以为n-m的m划分,即q(n-m,m);  最终得(1) + (2) = q(n,m-1) + q(n-m,m);



#include <stdio.h>
#include <stdlib.h>
//n的m划分,m为划分总和里的最大值
int q(int n,int m)
{
    if((n<1) || (m<1)) return 0;
    if(n == 1 || m == 1) return 1;//n = 1时,即{1},当m = 1时,即{1,1,1...1}n个1
    if(n == m) return q(n,m-1) + 1;//(1)n = m时,即{n}一个,(2)n的m-1的所有划分个数 (1) + (2) = q(n,m-1) + 1;
    if(n < m) return q(n,n);//实际情况没有这种情况的,所有和上一步相同即n = m 即 q(n,n);
    if(n > m) return q(n,m-1) + q(n-m,m);//(1)当不出现m时,即为n的m-1的所有划分个数,(2)当出现m时,{m,[x1,x2,x3...]},其中[x1,x2,x3...]中为n-m个,这里有可能出现m,所以为n-m的m划分,即q(n-m,m);  最终得(1) + (2) = q(n,m-1) + q(n-m,m);
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
        printf("%d\n",q(n,n));
    return 0;
}


你可能感兴趣的:(整数划分)