分治实例(一)求解正整数n划分成一系列正整数之和的种类数量
问题
整数划分问题,是将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。正整数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
思路
如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加一个自变量:将最大加数n1不大于m的划分个数记作q(n,m)。可以建立q(n,m)的如下递归关系:
q(n,m) = | 1 m,n = 0
| q(n,n) n < m
| 1 + q(n,n-1) n = m
| q(n,m-1) + q(n,m) n > m > 1
正整数n的划分数p(n)=q(n,n)
Python3的实现
def partition(n: int) -> list: """ 整数划分问题 将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。 正整数n的这种表示称为正整数n的划分。求正整数n的不同划分个数。 如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加一个自变量:将最大加数n1不大于m的划分个数记作q(n,m)。可以建立q(n,m)的如下递归关系。 q(n,m) = | 1 m,n = 0 | q(n,n) n < m | 1 + q(n,n-1) n = m | q(n,m-1) + q(n,m) n > m > 1 正整数n的划分数p(n)=q(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 :param n: :return: 返回多少种划分种类 """ return partition_1(n,n) def partition_1(n: int,m: int) -> list: """ 整数划分问题 将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。 正整数n的这种表示称为正整数n的划分。求正整数n的不同划分个数。 如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加一个自变量:将最大加数n1不大于m的划分个数记作q(n,m)。可以建立q(n,m)的如下递归关系。 q(n,m) = | 1 m,n = 0 | q(n,n) n < m | 1 + q(n,n-1) n = m | q(n,m-1) + q(n,m) n > m > 1 正整数n的划分数p(n)=q(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 :param n: :param m: 最大划分数字不超过m的划分数 :return: 返回多少种划分种类 """ if n <= 0: return -1 else: if n == 1 or m == 1: return 1 # 边界条件 elif n < m: return partition_1(n, n) # 递归方程 elif n == m: return 1 + partition_1(n, n-1) # 递归方程 else: return partition_1(n, m-1) + partition_1(n-m, m) # 递归方程