整数划分(递归)

来源:互联网 发布:linux安装jdk1.8 rpm 编辑:程序博客网 时间:2024/06/06 10:04

非常经典的问题 整数划分

把一个正整数n划分成一系列真整数的和  求有多少种划分的方式   第一反应就是递归分治写这道题 但是递归方程没有写出来   参考了别人的博客   他讲的很详细

这个人的~~


递归思路是酱紫的     首先把这个问题从求解n的划分数问题看成把n划分成一系列小于等于n的数字之和有多少种方法

我们设f(n , m)为把n划分成一系列数字之和  这些数字都小于m的划分种数;

如果n或者m等于1  那么 f(n,m) 等于 1;也就是只有全是1的这一种分类方法

然后当n > m  的时候我们讨论划分的情况中是不是含有m  如果不含有m的话 不含有m的情况我们可以表示为f(n , m - 1), 含有m的情况可以表示为f(n - m, m)(这里n!= m 注意) 


当n < m  的时候   种数相当于f(n , m);


当n == m的时候  我们再分成两种情况  第一种是划分种含有m  此时种数为1  (例如把 10划分  划分的数字中必须有10  只有一种分法 就是{10} ),  如果不含有m  那么就可以表示为f(n,m - 1);




#include <iostream>#include <cstring>using namespace std;int arr[55][56];int Recursion(int n, int m){if(arr[n][m])return arr[n][m];if(m == 1)return arr[n][m] = 1; if(n > m) return arr[n][m] = Recursion(n - m, m) + Recursion(n , m - 1);if(m > n) return arr[n][m] = Recursion(n , n);if(m == n) return arr[n][m] = 1 + Recursion(n , m - 1);}int main(){int t, n;memset(arr, 0, sizeof(arr));cin >> t;while (t --) {cin >> n;cout << Recursion(n , n) << endl;}}