赞
踩
正整数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划分。f(4,4)即为数字4的划分中最大加数不大于4的划分个数。
该问题是求出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)
AC代码:
#include<stdio.h>
#include<string.h>
int
p
(
int
n,
int
m){
if
((n<1)||(m<1))
return
0;
if
((n == 1)||(m == 1))
return
1;
if
(n < m)
return
p
(n,n);
if
(n == m)
return
p
(n,m-1)+1;
return
p
(n,m-1)+p(n-m,m);
}
int
main(){
int
N;
while
(
scanf
(
"%d"
,&N)!=EOF){
printf
(
"%d\n"
,p(N,N));
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。