正整数划分问题(递归优化)
来源:互联网 发布:html5 自适应表单源码 编辑:程序博客网 时间:2024/05/22 15:49
Description
将一个正整数n表示成一系列正整数的和,如:
N=n1+n2+…+nk (其中n1≥n2≥…≥nk≥1, k≥1)
正整数n的一个这种表示成为正整数n的一个划分。
现在给出一个正整数n(80≥n≥1),求n的不同划分一共有多少种。
Input
输入数据包含多组测试数据,每组测试数据只有一行,仅包含一个正整数n。
Output
对每组输入数据,输出一行,输出n的不同划分的种类数。
Sample Input
16
Sample Output
111
links:http://jsj.sdibt.edu.cn/JudgeOnline/showproblem?problem_id=1497
算法课本上的对正整数划分的讲解如下:
在正整数n的所有不同的划分中,将最大加数n1不大于m的划分个数记做q(n,m)。可以建立q(n,m)的如下递归关系。
① q(n,m) = 1, n >= 1 当最大加数n1不大于1时,任何正整数n只有一种划分形式,即 n = 1+1+1+~~~+1(n个1)
② q(n,m) = q(n,n) , m >= n 最大加数n1实际上不能大于n。因此, q(1,m) = 1。
③ q(n,n) = 1 + q(n,n-1) 正整数n的划分由n1 = n的划分和n1<=n-1 的划分组成
④ q(n,m) = q(n,m-1) + q(n - m,m) n>m>1 正整数n的最大加数n1不大于m的划分由n1 = m的划分和n1 < = m -1 的划分组成
PS:解释一下④ n1 = m时有: n1 + n -m = n 则此时的划分数目就是对n-m的划分,该划分中最大加数不大于m 即:q(n - m,m)
由以上关系可得
int IntegerDivide(int n,int m){if(n == 1 || m == 1) return 1;if(n == m) return(1+IntegerDivide(n,n-1));if(n < m) return IntegerDivide(n,n);if(n < 1 || m < 1) return 0;return IntegerDivide(n,m-1) + IntegerDivide(n-m,m);}
众所周知,递归的效率并不是很高,当测试数据量很大的时候无法AC于是乎必须进行优化
int InDiv(int n,int m){ int j = m,re = 0; while(j >= 1) { if(n == j) { if(ss[n][j] == 0) ss[n][j] == 1; re+=ss[n][j]; j--; continue; } if(n < j) {j = n; continue;} if(n == 1 || m == 1) { if(ss[n][j] == 0) ss[n][j] == 1; re+=ss[n][j]; return re; } if(ss[n][j] == 0) InDiv(n - j,j); re += ss[n][j]; j--; } return re;}
采用循环替代了部分递归,貌似没有优化多少,依旧TL。。。
再次改进:
int ss[81][81];int IntegerDivide(int n,int m){if(n == 1 || m == 1) {if(ss[n][m] == 0) ss[n][m] = 1;return ss[n][m];}if(n == m) {if(ss[n][m] == 0) ss[n][m] = 1+IntegerDivide(n,n-1);return ss[n][m];}if(n < m) {if(ss[n][m] == 0) ss[n][m] = IntegerDivide(n,n);return ss[n][m];}if(n < 1 || m < 1) {return 0;}if(ss[n][m] == 0) ss[n][m] = IntegerDivide(n,m-1) + IntegerDivide(n-m,m);return ss[n][m];}
对于已经计算过的q(n,m)进行存储提高了效率。。。
在网上看到别人写的代码附上挺牛的
#includeusing namespace std;int i,j,sum[88],s[100][100];int main(){s[0][0]=1;for(i=1;i<=80;i++)for(j=1;j<=i;j++){s[i][j]=s[i-1][j-1]+s[i-j][j];sum[i]+=s[i][j];};while(cin>>i){cout<
直接从1开始一个递推的计算出1-80所有数的证书划分存入sum。。。时间复杂度O(n^2)
- 正整数划分问题(递归优化)
- 整数划分问题(递归)
- 整数划分问题(递归)
- 正整数n的划分问题
- 整数划分问题(递归策略)
- 整数拆分(划分)问题 递归
- 整数划分问题(递归法)
- 整数划分问题(递归法)
- 整数划分问题(递归法)
- 整数划分问题(递归法)
- 整数划分问题(递归法)
- 整数划分问题(递归&递推)
- 递归--整数划分问题
- 递归-整数划分问题
- 递归-整数划分问题
- 递归---整数划分问题
- 递归-整数划分问题
- SeedCoder2014热身题7:正整数划分问题
- [WPF] 神奇的DockPanel
- About山寨机
- 用ODBC访问ACCESS模糊查找的问题
- 数据库零散知识
- qsort 线程不安全
- 正整数划分问题(递归优化)
- 光脚丫学LINQ(023):使用SQLMetal将对象模型生成为外部映射文件
- VMware“虚拟机无法锁定内存.....”错误解决方法
- xmlDoc在loadXML后,xmlDoc为null;Prolog 外部不能有 DOCTYPE 声明
- XMLHttpRequest 对象的几个方法和属性
- vmware 打开虚拟机时提示“该虚拟机似乎正在被使用”解决
- freemarker List 套 List
- DLL中使用DevExpress 皮肤 的问题
- XXXX面试题