非常经典的问题 整数划分
把一个正整数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 , n);
当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;
}
}