使用生成函数方法的解决方案
N(d, s)可能最容易编程。您可以使用递归很好地对问题建模:
public int numPossibilities(int numDice, int sum) { if (numDice == sum) return 1; else if (numDice == 0 || sum < numDice) return 0; else return numPossibilities(numDice, sum - 1) + numPossibilities(numDice - 1, sum - 1) - numPossibilities(numDice - 1, sum - 7);}乍一看,这似乎是一个相当简单有效的解决方案。但是你会发现相同的值,很多计算
numDice和
sum可重复并重新计算一遍又一遍,使可能比你原来的强制方法效率较低这一解决方案。例如,在计算
3骰子的所有计数时,我的程序
numPossibilities总共运行了函数一次
15106,而不是只
6^3= 216执行一次的循环。
为了使该解决方案可行,您需要添加另一种技术-
先前计算结果的记忆(缓存)。
HashMap例如,使用一个对象,您可以存储已经计算出的组合,并在运行递归之前先引用它们。当我实现一个缓存时,该
numPossibilities函数只运行
151总时间来计算
3骰子的结果。
随着骰子数量的增加,效率提高也越来越大(结果基于我自己实现的解决方案的仿真结果):
# Dice | Brute Force Loop Count | Generating-Function Exec Count3 | 216 (6^3) | 1514 | 1296 (6^4) | 2615 | 7776 (6^5) | 4016 | 46656 (6^6) | 5717 | 279936 (6^7)| 771...20 | 3656158440062976 | 6101



