题目链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2004
|
递归分析:
(n,m)代表对n进行划分,最大数为m的个数
1.递归时一共分四种情况,第一种 ( n == 1 | | m== 1 ),这时候(n,m)=1;
2.第二种 ( n < m ) ,就像对3划分,最大数为5,因为3最大划分成一个3,所以有(n,m)=(n,n);
3.第三种 ( n == m ) ,就像对3划分,最大数为3,这里可以分为两种情况,一种是划分为单独的一个3,一种是划分为最大为2的分法,即(n,m)=1+ ( n , n - 1 ) 。
4.第四种 ( n > m),这里对有划分后有没有最大数m进行讨论。
4.1如果划分后有最大数,就像对n进行划分,划分最大数为m,这种情况下划分后的数肯定包括一个m,即划分为{m,x1,x2,x3+....+xi },其中x1+x2+x3+.....+xi=n-m。这种情况就可以转化为对n-m划分,划分最大数为m,即(n,m)=(n-m,m)
4.2如果划分后无最大数,就像对n进行划分,划分最大数为m,因为划分是没有最大数m,则有(n,m)=(n,m-1)
综上所述:
if ( n == 1 | | m == 1 ) (n,m)= 1;
if ( n < m ) (n,m)=(n,n);
if ( n == m ) 1+ ( n , n - 1 ) ;
if ( n > m ) (n,m)=(n,m-1)
代码:
#include<iostream>
using namespace std;
int q(int n,int m)//对n进行划分,最大数为m
{
if(n==1||m==1)
return 1;
else if(n<m)
return q(n,n);
else if(n==m)
return 1+q(n,n-1);
else//拿最大数进行讨论,分有最大数和没最大数
return q(n-m,m)+q(n,m-1);
}
int main()
{
int n;
cin>>n;
cout<<q(n,n)<<endl;
return 0;
}
还有一种数的划分,就是对n进行划分,分成m个数字。
(n,m)代表对n进行划分,分成m个数字的个数
这里也是分几种情况,前几种就不说了,下面说一下最重要的一种情况。因为是分成m个数,所以每个数最小是1,这里面就可以对分之后有没有1再进行讨论。
1.如果分之后没有1,那么有(n,m)=(n-m,m);
2.如果分之后有1,那么有(n,m)=(n-1,m-1);
综上:
(n,m)=(n-m,m)+(n-1,m-1)
至于为啥是这样的,这里就不做详细的解释了,如果不会的话,可以多看看上面例题,分类讨论的思想类似,也可以看看这一题 分苹果。
这几题思路都是类似的,只要找到分类讨论的关键点,问题就迎刃而解了,写这种题最重要的就是学到这类题的做题方法