DynamicProgramming骰子总数的方式

时间:2016-03-08 17:46:26

标签: dynamic-programming

给定n个骰子,每个骰子有m个面,编号从1到m,找到获得和X的方法的数量.X是投掷所有骰子时每个面上的值的总和。 4 + 3和3 + 4应该对待相同。 不要考虑不同的排列。 n = 2,m = 6且X = 7的示例 没有办法应该是3(1,6和2,5和3,4)

2 个答案:

答案 0 :(得分:1)

我为你写了一个简短的Python代码:

d = {}


def f(n, m, x):
    if n == 0 and x == 0:
        return 1
    if n < 0 or m == 0 or x < 0:
        return 0
    if d.get((n, m, x)) is not None:
        return d[(n, m, x)]
    ret = f(n - 1, m, x - m) + f(n, m - 1, x)
    d[(n, m, x)] = ret
    return ret


print f(2, 6, 7) #return 3, as your example
print f(3, 6, 7) #return 4, (2 2 3), (1 3 3), (1 2 4), (1 1 5)

一个简单的解释:

f(n, m, x) = the ways of now we have n dices, and now the dice numbered from 1 to m to achieve sum x.

f(n, m, x) = f(n - 1, m, x - m) + f(n, m - 1, x)

然后

f(n - 1, m, x - m): throw a dice and it must be number m.
f(n, m - 1, x): don't throw a dice, and we let the dice number decrease 1(so we can't throw a dice with number m now, it could be m-1 as most)

为什么我们必须扔一个数字为m的骰子?哦,就这样,我们可以得到一个与其他解决方案不同的解决方案(我的意思是避免将3+44+3作为不同的解决方案)。

通过记忆总结以上内容(如果你不了解记忆,你可以学习一些关于动态编程的基本知识),我们来解决。

答案 1 :(得分:0)

希望有帮助!

import itertools

face = 6
throw = 3
sum_ = 12

combinations = itertools.combinations_with_replacement(list(range(1,face+1)), throw)
a = []
c = 0
for i in combinations:
    if sum(i) == sum_ :
        c = c +1
        for j in itertools.permutations(i):
            if j not in a:
                a.append(j)
print("With repetitions",len(a))
print("Without repetitions",c)