python - 找出可能达到结果的整数组合的数量
问题描述
我有点卡在python问题上。
我想写一个函数,它接受一个正整数 n 并返回不同操作的数量,这些操作可以和 n (2<n<201) 并带有递减和唯一的元素。举个例子:如果 n = 3 那么 f(n) = 1(因为唯一可能的解决方案是 2+1)。如果 n = 5,则 f(n) = 2(因为可能的解是 4+1 和 3+2)。如果 n = 10 那么 f(n) = 9 (因为可能的解是 (9+1) & (8+2) & (7+3) & (7+2+1) & (6+4) & ( 6+3+1) & (5+4+1) & (5+3+2) & (4+3+2+1))。
对于我这样开始的代码:
def solution(n):
nb = list(range(1,n))
l = 2
summ = 0
itt = 0
for index in range(len(nb)):
x = nb[-(index+1)]
if x > 3:
for index2 in range(x-1):
y = nb[index2]
#print(str(x) + ' + ' + str(y))
if (x + y) == n:
itt = itt + 1
for index3 in range(y-1):
z = nb[index3]
if (x + y + z) == n:
itt = itt + 1
for index4 in range(z-1):
w = nb[index4]
if (x + y + z + w) == n:
itt = itt + 1
return itt
它在 n 很小的时候起作用,但是当你开始在 n=100 左右时,它非常慢,我需要添加更多的 for 循环,这会使情况恶化......
你知道我该如何解决这个问题吗?我错过了一个明显的解决方案吗?
解决方案
这个问题被称为整数分割成不同的部分。OEIS 序列(值减 1,因为您不需要n=>n
case )
我已经有了将分区划分为 k 个不同部分的代码,因此对其进行了一些修改以将分区数计算为任意数量的部分:
import functools
@functools.lru_cache(20000)
def diffparts(n, k, last):
result = 0
if n == 0 and k == 0:
result = 1
if n == 0 or k == 0:
return result
for i in range(last + 1, n // k + 1):
result += diffparts(n - i, k - 1, i)
return result
def dparts(n):
res = 0
k = 2
while k * (k + 1) <= 2 * n:
res += diffparts(n, k, 0)
k += 1
return res
print(dparts(201))