0804 OpenJ#7215 简单的整数划分问题

来源:互联网 发布:淘宝买家怎么实名认证 编辑:程序博客网 时间:2024/05/20 18:00
摘要:递归使用中将问题化为更小的同类子问题
原题目链接简单的整数划分问题

描述

将正整数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
来源: http://cxsjsxmooc.openjudge.cn/2017t2summerw3/2/



题目理解:递归中的化为更小问题的表现在递归方法的总体思想是将待求解问题的解看作输入变量 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;}


原创粉丝点击