📅  最后修改于: 2023-12-03 15:23:00.606000             🧑  作者: Mango
给定一个正整数 n
和一个正整数序列 a1, a2, ..., ak
,满足:
i
,都有 1 <= ai <= n
。i != j
,都有 ai != aj
。我们定义一个序列 b1, b2, ..., bk
为 n
的一个非负积分解,当且仅当:
i
,都有 0 <= bi <= n - ai
。n
,即 b1 + b2 + ... + bk = n
。本文介绍如何使用动态规划来计算和方程的非负积分解的数量。
设 dp[i][j]
表示使用前 i
个数,和为 j
的非负积分解的数量。
则有以下状态转移方程:
dp[i][j] = dp[i-1][j] + dp[i][j-i]
其中,第一项表示不选择第 i
个数,第二项表示选择第 i
个数,且将其加入到和为 j-i
的序列中。
最终答案为 dp[k][n]
。
def non_negative_integer_partitions(n: int, a: List[int]):
k = len(a)
A = [True] * (n + 1)
for ai in a:
A[ai] = False
dp = [[0] * (n + 1) for _ in range(k + 1)]
dp[0][0] = 1
for i in range(1, k + 1):
for j in range(n + 1):
dp[i][j] = dp[i-1][j]
if j >= a[i-1] and A[j-a[i-1]]:
dp[i][j] += dp[i][j-a[i-1]]
return dp[k][n]
注:参数 A
表示是否为原序列中的值,A[i] = True
表示 i
不在序列中。