整数划分问题
题目描述
将正整数n表示为一系列正整数之和,
n=n1+n2+n3+n4+......+nk
(其中,n1>=n2>=n3>=n4........>=nk>0,k>=1)
正整数n的这种表示成为正整数n的划分。正整数n的不同划分个数成为正整数n的划分数,记作p(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;
这是一道比较绕的递归问题,绕就绕在数学上,有点不好理解。
引入变量m表示最大加数,由上图分析可得
q( n, n ) = 1, 当 n ==1;
q( n, n ) = 1, 当m == 1;
q( n, n ) = q( n,n ) , 当n < m;
q( n, n ) = q( n, m-1) +1 , 当n == m;
q( n, n ) = q( n - m, m ) + q( n , m -1) , 当n > m;
也就是说,当m=n时,递归1+q( n, m-1) 比如m=n=6最大加数为6,则递归1+q(6,5),1既是6这种情况然后加上最大加数为5的所有情况,而最大加数为5仍需递归。
这时候n=6,m=5 又分为两种,q(6,4)即最大加数为4的所有情况和q(1,5)
如此再对q(6,4)递归
而当m或n等于1时只有1种情况也就是达到边界
递归结束后既出答案
#include<bits/stdc++.h>
using namespace std;
int q(int n,int m)
{
if(n==1||m==1){
return 1;
}else if(n>m){
return q(n-m,m)+q(n,m-1);
}else if(n<m){
return q(n,n);
}else{
return 1+q(n,n-1);
}
}
int main()
{
double start,stop,dur;
start=clock();
int a=6;
cout<<q(6,6);
stop=clock();
dur=stop-start;
cout<<"\n用时:"<<dur<<"毫秒\n";
return 0;
}