人物 - Apple Puzzle [灵感来自客户端 - 益智协议]

时间:2015-02-12 13:17:12

标签: math probability puzzle

我正在学习一个客户端拼图协议,我有一个关于找到解决方案可能性的问题。这里有一个场景,而不是进入干燥的协议事实:

假设我有x个人,我有y苹果:

  • 每个人必须至少拥有1个苹果
  • 每个人最多可以拥有z个苹果。

是否有计算方案数量的公式?

实施例: 4人[x],6个苹果[y],15个MAX苹果[z]

没有。手工计算的情景:10。

如果我的数字很大,我希望用公式计算它。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您的问题等同于"通过将x个数字加在一起,找到可以获得z的方式的数量,每个数字位于min和{{1}之间}&#34。示例Python实现:

max

结果:

def possible_sums(x, z, min, max):
    if min*z > x or max*z < x:
        return 0
    if z == 1:
        if x >= min and x <= max:
            return 1
        else:
            return 0
    total = 0
    #iterate from min, up to and including max
    for i in range(min, max+1):
        total += possible_sums(x-i, z-1, min, max)
    return total

print possible_sums(6, 4, 1, 15)

使用大数字调用此函数会变得非常昂贵,但使用memoization可以改善运行时间。如何实现这一点取决于语言,但传统的Python方法是将先前计算的值存储在字典中。

10

现在def memoize(fn): results = {} def f(*args): if args not in results: results[args] = fn(*args) return results[args] return f @memoize def possible_sums(x, z, min, max): #rest of code goes here 需要花费很长时间才能计算,会立即返回print possible_sums(60, 40, 1, 150)

答案 1 :(得分:0)

有数学方法可以做到这一点。它类似于询问有多少种方法可以在3个6面骰子上滚动总共10个(x = 3,y = 10,z = 6)。您可以通过几种不同的方式实现此目的。

一种方法是使用包含 - 排除。将y作为x正数之和而没有最大值的方法的数量是y-1,由stars-and-bars argument选择x-1。您可以计算将y作为x正数之和的方式的数量,以便如果yx-sz为负,则y的一个特定的s组至少为z + 1:0,并且y-1-sz选择x- 1如果它是非负的。然后你可以使用inclusion-exclusion将计数写为s的非负值的总和,使yx-sz为(-1)^ s(x选择s)的非负(y-1-sz选择x-1) )。

enter image description here

您可以使用生成功能。你可以让一些变量的权力,比如t,保持总数,系数表示总数的组合数。然后你要求(t + t ^ 2 + ... + t ^ z)^ x中的t ^ y系数。您可以通过几种方式计算出来。

一种方法是动态编程,计算k到x的(t + t ^ 2 + ... + t ^ z)^ k的系数。天真的方法可能足够快:你可以计算k = 1,2,3,...,x。使用诸如重复平方之类的东西要快一点,例如,计算第87次幂,你可以将二进制扩展为87 + 64 + 16 + 4 + 2 + 1 = 0b1010111(写成二进制文字)。您可以通过平方和乘法计算第1,第2,第4,第16和第64功率,或者您可以通过squaring and multiplying计算0b1,0b10,0b101,0b1010,0b10101,0b101011和0b1010111功率来保存小空间。

另一种方法是使用二项式定理两次。

(t+t^2+...+t^z)^x = t^x ((t^z-1)/(t-1))^x 
                  = t^x (t^z-1)^x (t-1)^-x. 

带有指数x的二项式定理让我们将(t ^ z-1)^ x重写为(-1)^ st ^(z(xs))之和(x选择s),其中s的范围从0到x 。它还允许我们将(t-1)^ - x重写为(r + x-1选择x-1)t ^ r与非负r的无限和。然后我们可以选出有助于t ^ y系数的有限项集(r = y-x-sz),并得到与上面的包含 - 排除相同的和。

例如,假设我们有x = 1000,y = 1100,z = 30。值是

enter image description here

= 1.29 x 10 ^ 144。