整数划分问题 递归优化

递归的划分 比较容易理解 但是极易time out

若要把n用不大于n的数m划分

总共分四种情况 

1.若n==m  则只有一种 但是要继续递归 所以等于 1+q(n,m-1)

2.若n<m 则不用考虑 无法划分 则 继续使用 q(n,n)

3.若n>m 则有两种情况   1.用m划分 剩余则是n-m  因此等于 q(n-m,m)

             2.用小于m的数继续划分  则是 q(n,m-1)

             3.所以合起来是  q(n-m,m)+q(n,m-1)

4.最后就是递归出口了   最底层肯定是1 

1 if(n==1 ||m==1)

2     return 1;

 

完整代码如下

 1 #include "stdio.h"

 2 int q(int n,int m)

 3 {

 4     if(n==1 ||m==1)

 5         return 1;

 6     if(n<m)

 7         return    q(n,n);

 8     if(n==m)

 9         return 1+q(n,m-1);

10     if(n>m)

11         return q(n-m,m)+q(n,m-1);

12 } 

13 main()

14 {

15     int n;

16     while(scanf("%d",&n)!=EOF)

17     {

18         printf("%d\n",q(n,n));

19     }

20 } 

 

 若要避免溢出 一种比较好的办法 就是采用 记忆式的递归 

 也就是说在每一次递归结束之后 把你的结果保存起来  当下一次递归的时候 直接取出来就行 不用再向下递归

 

 1 #include "stdio.h"

 2 int  a[121][121];

 3 int q(int n,int m)

 4 {

 5     

 6     if(n==1 ||m==1)

 7         return a[n][m]=1;

 8     if(n<m)

 9         return   q(n,n);

10     if(a[n][m]!=0)

11         return a[n][m];

12     if(n==m)

13         return a[n][m]=1+q(n,m-1);

14     if(n>m)

15         return a[n][m]=q(n-m,m)+q(n,m-1);

16 } 

17 main()

18 {

19     int n;

20     while(scanf("%d",&n)!=EOF)

21     {

22         q(n,n);

23         printf("%d\n",a[n][n]);

24     }

25 }

 

你可能感兴趣的:(递归)