对于一个正整数 n 的划分,就是把 n 变成一系列正整数之和的表达式。注意,划分与顺序无关,例如 6=5+1.跟 6=1+5 是同一种分划,
另外,这个整数本身也是 一种分划。
例如:对于正整数 n=5,可以划分为:
1+1+1+1+1
1+1+1+2
1+1+3
1+2+2
2+3
1+4
5
输入描述
输入一个正整数 n
输出描述
输出 n 整数划分的总数
输入样例 5
输出样例 7
这个问题整数的划分问题,我更愿称之为分苹果问题。
即给n个苹果,m个盘子。总共有多少种分法。
首先,当苹果少,盘子多。即n<m.
此时,你会发现无论怎么分,肯定有盘子是没有苹果的。因为按n个苹果最多只能占用n个盘子。
那么我们不妨,假设m个盘子依次排开,这时随着分法的改变,只有前n个盘子里面的苹果数量在改变,而后m-n个盘子始终为空。那么这就意味着这个问题只与前n个盘子有关。
即当n<m时,f(n,m)=f(n,n)
(当然如果n<=m,也肯定存在有盘子没苹果的分法,但也肯定存在苹果分完后不存在空盘子的情况,因此此时上述等式肯定是不成立的)
其次,当苹果多,盘子少。即n>=m
此时,一定存在着每个盘子上都存在着苹果的情况,以及有的盘子上没有苹果的情况。
通过思考我们可以得出,此时的总分法可以分为
1.每个盘子上都至少存在着一个苹果。即每一个盘子上一定至少有一个苹果。
2.存在至少一个盘子没有苹果。即有的盘子没有苹果。
很显然,所有的分法就等于分法一和分法二的和。
那么对于分法一,我们很容易抽象出来函数f(n-m,m).即只剩下n-m个苹果需要在m个盘子上去分。
而对于分法二,抽象出来一个函数并不是很容易。那么接下来我们思考这句话至少有一个盘子上是不存在苹果的。我们不妨认为这个盘子就是第一个盘子。第一个盘子上面不存在苹果。那这个问题就变成了m-1个盘子分n个苹果。即抽象出来函数f(m-1,n)
所以当n>=m 时
f(n,m)=f(n-m,m)+f(n,m-1)
最后显然,当盘子为一个或者苹果为一个的时候,此时只有一种分法。
而对于盘子为0个或者苹果为0个,定义也只存在一种分法。
那么代码如下:
#include <iostream>
using namespace std;
int main()
{
int n;
int apple(int n,int m);
cin >> n;
cout << apple(n,n) << endl;
return 0;
}
int apple(int n,int m)
{
if(n<=1 || m<=1)
return 1;
if(m>n)
return apple(n,n);
if(n>=m)
return apple(n-m,m) + apple(n,m-1);
}