总共有N个不同的球盒。有P个盒子,每个盒子包含许多球,剩下的Q盒每个都包含B个球。
给定数字X,你可以从盒子里挑选至少X球的方式总数是多少。
P + Q = N
示例:Number of P boxes=2
每个包含2个球,Number of Q boxes=1
包含2个球。 X=3(Given)
其中x=minimum number of balls to be picked
所以,P + Q = 3(总箱数)
选择至少x即3球的方式的组合将是:
3的组合:(111),(210),(120),(021),(012),(201),(102)
4的组合:(220)(202)(022)(211)(121)(112)
组合5:(212)(122)(221)
组合6:(222)
总组合:17
我的方法:
我已经使用了"星和酒吧方法":
计算6:x + y + z = 6的组合,将其转换为(2-x)+(2-y)+(2-z)= 6,得出x + y + z = 0。登记/> 因此,6的组合变为二项式(2C2)= 1
类似地,5的组合变为二项式(3C2)= 3
组合4 =二项式(4C2)= 6
3 =二项式(5C2)= 10的组合
1+3+6+10=20
but the answer should be 1+3+6+7=17
在计算3的组合时出现了边缘情况。我应该如何解决这个问题?
编辑:在Python中添加代码
global total_combinations
total_combinations=0
from math import factorial
def combinations(a):
global total_combinations
bars=numberofAs+numberofBs-1
stars=a
total_combinations+=factorial(stars+bars)/(factorial(bars)*factorial(stars))
numberofAs,numberofBs,numberofballsinA,numberofballsinB=map(int,raw_input().split())
x=int(raw_input())
operational_array=[]
for i in range(numberofAs):
operational_array.append(numberofballsinA)
for i in range(numberofBs):
operational_array.append(numberofballsinB)
max_x=sum(operational_array) #calculate combinations from x to max_x
k=max_x
for i in range(max_x,x-1,-1):
k=max_x-i
combinations(k)
print total_combinations
答案 0 :(得分:1)
你可以在一个包含A球的盒子中 out 的球数是你可以将放入一个空盒容量A的球数。 已知有该问题的公式。
如果所有盒子最初都有相同数量的球(如给定的例子,其中A = B = 2),
并且这个数字等于或大于要从盒子中取出的球的总数,那么"星和条"将工作。
但是如果要移除的球的数量大于单个框中的数量,则存在迭代公式以找到可以选择球的方式的数量。
要从t
每个包含k
个球的框中删除m
个球,
from scipy.special import comb
def combinations_with_limit(t, k, m):
total = 0
max_full_boxes = min(k, int(t/(m + 1)))
for i in range(max_full_boxes + 1):
total += int((-1)**i) * comb(k, i, exact=True) * comb(t + k - 1 - i*(m + 1), k - 1, exact=True)
return total
这是基于公式in this math.stackexchange answer,但使用t
而不是n
来删除球的总数,以避免在此问题中使用N时出现混淆。
当然,您可以优化和改进此代码的样式
(例如,我不建议在生产代码中编写int((-1)**i)
);
它以这种方式书写的原因是尽可能接近MSE答案的格式。
毫不奇怪,在A和B不同的情况下,我们必须更加努力。
要从t
个包含p
个方框的a
个方框中删除总计q
个球,每个包含b
个球的def combinations_with_two_limits(t, p, q, a, b):
total = 0
min_balls_from_p = max(0, t - q*b)
max_balls_from_p = min(t, p*a)
for i in range(min_balls_from_p, max_balls_from_p + 1):
total += combinations_with_limit(i, p, a) * combinations_with_limit(t - i, q, b)
return total
个方框
t
这里的想法是你首先决定如何将a
球分成两组,一组从包含b
球的方框中移除,另一组从包含combinations_with_two_limits
的方框中删除{1}}球,
然后计算所有可以从这些框的子集中选择球的子集的方法。
通过回到上面引用的MSE公式的推导(通过生成函数或包含 - 排除原则)可以进一步优化代码,但我不会尝试它,除非它真的至关重要的是减少运行时间的几个百分点。
要从框中删除至少X个球,请取值的总和
t
为P*A + Q*B
,取自X的所有整数值,包括您可以移除的最大数量的球
(Jan 26 00:00:15
)。
答案 1 :(得分:0)