python - 整数的不同分区,不包括重复组合
问题描述
我在某处在线找到了这段代码,我试图弄清楚它是如何工作的。您为 partitions() 函数提供一个整数,代码返回不包括重复数字的不同分区的数量(例如 n = 5 -> 2 个分区 (3,2) & (4,1))。我想了解这个递归解决方案究竟是如何管理这个的。我一直在玩弄代码,跟踪递归调用,但我仍然不太明白它是如何工作的。请帮我理解。
def partitions(n):
memo = [[0 for _ in range(n + 2)] for _ in range(n + 2)]
return bricks(1, n, memo) - 1
def bricks(h, l, memo):
if memo[h][l] != 0:
return memo[h][l]
if l == 0:
return 1
if l < h:
return 0
memo[h][l] = (bricks(h + 1, l - h, memo)) + (bricks(h + 1, l, memo))
return memo[h][l]
解决方案
这似乎是OEIS A111133,划分n
为至少 2 个不同部分的数量。
忘记所有琐碎的东西memo
- 这只是一种优化,并掩盖了意图。剩下的变量名很糟糕。我将使用L
andH
代替(至少L
不会 - 像l
- 容易与数字 1 混淆)。
bricks(H, L)
似乎是 L 分成不同部分的数量,其中最少的部分至少是 H。其中有多少?那么,H
是在这样一个分区,或者它不是。如果H
是,则L-H
仍然存在,并且需要将其划分为最少的部分,其中至少是H+1
。如果H
不在这样的分区中,则L
保留,并且需要将其分成最少的部分,其中最少为H+1
. 将这些相互排斥的情况加在一起:
bricks(H, L) = bricks(H+1, L-H) + bricks(H+1, L)
如果L < H
,则没有L
至少有一个部分的分区H
,所以为 0。由于bricks(L, L)
必须为 1(显然有 1 个至少有一个部分的分区L
)L
,因此需要bricks(H, 0)
返回 1 才能计算出上述总和。
最后,n
分成至少 2 个不同部分的分区数是分成n
至少1 个不同部分的分区数bricks(1, n)
- 减去单例分区{n}
(该分区没有至少 2 个不同部分)。
理解这里的障碍并不是代码本身——而是找出代码背后的想法。
推荐阅读
- go - 如何使用扫描仪bufio
- android - 从标签布局Android中获取列表中的所有标签(标签)标签
- mongodb - 如何在 MongoDB 中编写一个查询(计数不同,总和)?
- api - 不带斜线的邮递员路径变量
- c# - C#:如何在 MessageBox 中显示换行符
- swift - AVAssetWriter 录制的音频没有声音
- swift - 如何正确地将 If 语句合并到我的 Swift 代码中?
- laravel - 如何从相关模型中仅获取 id
- c++ - 将 char 传递给具有 char 参数的函数有什么问题
- java - 如何处理 setOnClickListener 以在 android 中动态添加按钮?