带单次最多k块约束的3人巧克力分配方式计数问题求解
正确解法:分配N块巧克力给3个孩子(每人最多k块)的方式数
问题核心
我们需要计算有序非负整数解的个数:满足 x₁ + x₂ + x₃ = n,且每个 xᵢ ≤ k(i=1,2,3)。孩子是不同个体,因此[2,0,0]和[0,2,0]视为不同分配方式。
容斥原理推导公式
利用隔板法结合容斥原理,步骤如下:
- 无限制条件的解数:用隔板法,非负整数解的个数为组合数
C(n+2, 2)(公式:C(n + m -1, m-1),m=3个孩子)。 - 减去至少1个孩子超过k块的情况:选1个孩子先分
k+1块,剩余n-(k+1)块再分配,解数为C(3,1) * C(n-(k+1)+2, 2),仅当n ≥ k+1时有效,否则该项为0。 - 加回至少2个孩子超过k块的情况:选2个孩子各分
k+1块,剩余n-2*(k+1)块分配,解数为C(3,2) * C(n-2*(k+1)+2, 2),仅当n ≥ 2*(k+1)时有效。 - 减去3个孩子都超过k块的情况:每个孩子先分
k+1块,剩余n-3*(k+1)块分配,解数为C(3,3) * C(n-3*(k+1)+2, 2),仅当n ≥ 3*(k+1)时有效。
最终公式:
total = C(n+2,2) - C(3,1)*C(n-(k+1)+2,2) (n≥k+1时生效) + C(3,2)*C(n-2*(k+1)+2,2) (n≥2*(k+1)时生效) - C(3,3)*C(n-3*(k+1)+2,2) (n≥3*(k+1)时生效)
注:若计算中组合数的上标小于下标(如n-(k+1)为负数),则该项视为0;最终结果需取非负值(比如n>3k时无合法解,结果为0)。
Python代码实现
from math import comb def count_distribution_ways(k, n): total = comb(n + 2, 2) if n >= 0 else 0 # 减去至少1个孩子超量的情况 if n >= k + 1: total -= comb(3, 1) * comb(n - (k+1) + 2, 2) # 加回至少2个孩子超量的情况(容斥修正) if n >= 2 * (k+1): total += comb(3, 2) * comb(n - 2*(k+1) + 2, 2) # 减去3个孩子都超量的情况 if n >= 3 * (k+1): total -= comb(3, 3) * comb(n - 3*(k+1) + 2, 2) return max(total, 0) # 验证示例1 k1, n1 = 2, 2 print(f"maximum number of ways: {count_distribution_ways(k1, n1)}") # 输出6,符合预期 # 验证示例2 k2, n2 = 5, 15 print(f"maximum number of ways: {count_distribution_ways(k2, n2)}") # 输出1,符合预期
纠正你之前的错误
你之前的代码存在两个关键问题:
- 组合数的选择项错误:应根据i的取值对应
comb(3,i),而非统一用comb(3,1)。 - 缺少有效性判断:当
n - i*(k+1)为负数时,对应的组合数需视为0,否则会计算出错误结果。
内容的提问来源于stack exchange,提问作者Gaurav Shrivastava
相关产品推荐
相关产品推荐

