问题描述:
整数划分问题是算法中的一个经典命题之一,有关这个问题的讲述在讲解到递归时基本都将涉及。所谓整数划分,是指把一个正整数n写成如下形式:
n=m1+m2+...+mi; (其中mi为正整数,并且1 <= mi <= n),则{m1,m2,...,mi}为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
思路:
由于只用一个参数不容易表示,用递归解决此问题时,我们采用了n,m两个参数。n表示要求的整数,m表示组成正整数n的最大整数n1的最大取值。对于每个正整数n,如果构成它的最大正整数n1=m,那么种类就应该等于f(n-m,m),如果n1<m,则应等于f(n,m-1).终上所述,f(n,m) = f(n-m,m)+f(n,m-1) ,n>m; 若是n == m,则f(n,m)=1+f(n,m-1); 若是n<m ,则f(n,m)=f(n,n) ; 若是n = 1或m = 1,则f(n,m) = 1;
具体表达式如下图所示:
以7为例:可做如下例子
运行结果:
递归函数:
void f(int n,int m)
{
if(n==1 || m==1)
return 1;
else if(n<m)
return f(n,n);
else if(n==m)
return f(n,m-1) + 1;
else
return f(n,m-1)+f(n-m,m);
}
完整代码:
#include <iostream>
#include <bits/stdc++.h>
#include <string>
using namespace std;
//整数划分问题
int int_part(int n,int m)
{
if(m==1)
return 1;
else if(n == 1)
return 1;
else if( n< m)
return int_part(n,n);
else if(n == m)
return 1+int_part(n,m-1);
else
return int_part(n,m-1)+int_part(n-m,m);
}
int main()
{
int n;
cin>>n;
cout<<int_part(n,n);
return 0;
}