算法笔记——整数划分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

posted @ 2015-07-02 20:13 DwyaneTalk 阅读(...) 评论(...) 编辑 收藏