摘要:递归使用中将问题化为更小的同类子问题
原题目链接:简单的整数划分问题
描述
将正整数n 表示成一系列正整数之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 。
正整数n 的这种表示称为正整数n 的划分。正整数n 的不同的划分个数称为正整数n 的划分数。
输入
标准的输入包含若干组测试数据。每组测试数据是一个整数N(0 < N <= 50)。
输出
对于每组测试数据,输出N的划分数。
样例输入
5
样例输出
7
提示
5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1
将正整数n 表示成一系列正整数之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 。
正整数n 的这种表示称为正整数n 的划分。正整数n 的不同的划分个数称为正整数n 的划分数。
5
7
题目理解:递归中的化为更小问题的表现在 递归方法的总体思想是将待求解问题的解看作输入变量 x 的函数 f(x),通过寻找函 数 g,使得 f(x) = g(f(x-1)),并且已知 f(0)的值,就可以通过 f(0)和 g 求出 f(x)的值。这 样一个思想也可以推广到多个输入变量 x,y,z 等,x-1 也可以推广到 x - x1,只要递 归朝着出口的方向走就可以了 。
本题的类型转化同一个叫做放苹果的题目,本题求n的m个数划分记为f(n,m) 对于n与m的关系就可以转换问题到更小的规模,当n>=m时 和f(n-m,m)+f(n,m-1)是一样的(及假设各个数不为0那么把他们全部减一效果是一样的,另外就是至少有一个0,那么与m-1是一样的) n<m时 与f(n,n)是一样的。不断转化直到 n==0||m==0的情况。
注意:递归中储存了递归的结果,因此速度会比较快。不过要是要输出各个划分的话 可能又不好实现了。
日期:
2017 8 4
附加:
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <memory.h>
using namespace std;
int F[60][60];
int f(int n,int m){
if(F[n][m]==-1){
if(n==0) return F[n][m]=1;
if(m==0) return F[n][m]=0;
if(n>=m){
return F[n][m]=f(n-m,m)+f(n,m-1);
}
if(n<m){
return F[n][m]=f(n,n);
}
}
return F[n][m];
}
int main(){
memset(F,-1,sizeof(F));
int n;
while(~scanf("%d",&n))printf("%d\n",f(n,n));
return 0;
}