算法笔记——整数划分1
题目来源:NYOJ90
问题描述:
将正整数n表示成一系列正整数之和:n=n1+n2+…+nk, 其中n1≥n2≥…≥nk≥1,k≥1。 正整数n的这种表示称为正整数n的划分。求正整数n的不 同划分个数。
例如正整数6有如下11种不同的划分:
6;
5+1;
4+2,4+1+1;
3+3,3+2+1,3+1+1+1;
2+2+2,2+2+1+1,2+1+1+1+1;
1+1+1+1+1+1。
输入:
第一行是测试数据的数目M(1<=M<=10)。以下每行均包含一个整数n(1<=n<=10)。
输出:
输出每组测试数据有多少种分法。
分析:
对于整数划分,相当于把正整数n写成下面形式:
n=n1+n2+…+nk (其中n≥n1≥n2≥…≥nk≥1,k≥1),则{n1, n2, ……,nk}为n的一个划分。
现假设n1 <= m,即:{n1, n2, ……,nk}中最大的数不超过m,则称{n1, n2, ……,nk}是n的一个m上限划分。记n的m上限划分为f(n,m)。因此,此题的解便是f(n,n)。对于f(n,m),分析可得下面的递推关系式:
1、当n = 1时,f(n,m)=1。即1只有{1}这一种划分。
2、当m = 1时,f(n,m)=1。即此时只有{1, 1,……,1}(共n个1)这一种划分。
3、当m = n时,f(n,m) = f(n,n) = f(n, n-1) + 1。其中"+1"对应的就是{n}这种划分,其他的划分中,必定所有数都小于n。
4、当m > n时, f(n,m) = f(n,n),因为n的划分中不可能存在大于n的数。
5、当m < n时, f(n,m) = f(n-m, m) + f(n, m-1)。其中f(n-m,m)表示包含m的划分,f(n,m-1)表示不包含m的划分。
代码:
根据上面的递推式,同样可以写出递归和递推的代码。
递归代码仍然存在重复计算,时间代价大。
递推代码就是计算f(1,1)到f(n,n)的过程,所以时间和空间复杂度都是O(n^2),而且由于f(n,m)是和f(n-m,m)、f(n,m-1),所以不太适合进行空间复杂度的优化。
代码见github:整数划分1