当前位置: 首页 > 面试题库 >

计算滚动一定数量的方式的数量

于恺
2023-03-14
问题内容

我是一名高中计算机科学系的学生,今天遇到一个问题:

程序说明:掷骰子的人相信,掷三个骰子,十个比掷九个更容易。您可以编写一个证明或否定这一信念的程序吗?

让计算机计算所有可能的投掷三个骰子的方法:1 + 1 + 1,1 + 1 + 2,1 + 1 +
3,依此类推。将这些可能性中的每一个相加,然后看看有多少会给出九个有多少给十。如果多给十,那么信念就会得到证明。

我很快想出了一种蛮力解决方案

int sum,tens,nines;
    tens=nines=0;

    for(int i=1;i<=6;i++){
        for(int j=1;j<=6;j++){
            for(int k=1;k<=6;k++){
                sum=i+j+k;
                //Ternary operators are fun!
                tens+=((sum==10)?1:0);
                nines+=((sum==9)?1:0);
            }
        }

    }
    System.out.println("There are "+tens+" ways to roll a 10");
    System.out.println("There are "+nines+" ways to roll a 9");

哪种方法很好用,而暴力破解解决方案是老师想要我们做的。但是,它不适合,我试图找到一种方法,使算法可以计算的方式来卷数 Ñ
骰子得到一个具体的数字。因此,我开始生成获取具有 n个
骰子的每个和的方法的数量。对于1个模具,显然每个模具都有1个解决方案。然后,我通过蛮力计算了2个和3个骰子的组合。这些是针对两个的:

有1种滚动方式2
有2种滚动方式3
有3种滚动方式4
有4种滚动方式5
有5种滚动方式6
有6种滚动方式7
有5种滚动方式8 8
种滚动方式9
一种3种滚动方式10
一种2种滚动方式11
一种1种滚动方式12

看起来很简单;可以使用简单的线性绝对值函数进行计算。但是,事情开始变得棘手。与3:

有1种滚动方式3
有3种滚动方式4
有6种滚动方式5
有10种滚动方式6
有15种滚动方式7
有21种滚动方式8
有25种滚动方式9
有27种滚动方式10
有27种滚动方式11
有25种滚动方式12
有21种滚动方式13
有15种滚动方式14
有10种方式滚动15滚动
6有6种
方法滚动17滚动有3种
方法滚动18滚动有1种方法

所以我看了一下,我想:很酷的三角数!但是,然后我注意到那些讨厌的25和27。因此,显然它不是三角数,而是一些多项式展开式,因为它是对称的。
因此,我进入了Google,我在此页面上找到了有关如何使用数学方法进行此操作的详细信息。使用重复的导数或扩展来找到它是很容易的(尽管很长),但是对我来说很难编程。我不太了解第二和第三个答案,因为我以前从未在数学学习中遇到过这种记号或那些概念。有人可以请我解释一下如何编写程序来执行此操作,或者请解释该页面上给出的解决方案,以使我对组合技术有所了解。

编辑:我正在寻找一种数学方法来解决此问题,它提供了一个准确的理论数字,而不是通过模拟骰子


问题答案:

使用生成函数方法的解决方案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);
}

乍一看,这似乎是一个相当简单有效的解决方案。但是你会发现相同的值,很多计算numDicesum可重复并重新计算一遍又一遍,使可能比你原来的强制方法效率较低这一解决方案。例如,在计算3骰子的所有计数时,我的程序numPossibilities总共运行了函数一次15106,而不是只6^3 = 216执行一次的循环。

为了使该解决方案可行,您需要添加另一种技术-
先前计算结果的记忆(缓存)。HashMap例如,使用一个对象,您可以存储已经计算出的组合,并在运行递归之前先引用它们。当我实现一个缓存时,该numPossibilities函数只运行151总时间来计算3骰子的结果。

随着骰子数量的增加,效率提高也越来越大(结果基于我自己实现的解决方案的仿真结果):

# Dice | Brute Force Loop Count | Generating-Function Exec Count
3      | 216 (6^3)              | 151
4      | 1296 (6^4)             | 261
5      | 7776 (6^5)             | 401
6      | 46656 (6^6)            | 571
7      | 279936 (6^7)           | 771
...
20     | 3656158440062976       | 6101


 类似资料:
  • 问题内容: 样本数据可能会有助于解释我想做的事情,而不是解释它,因此,我将从此开始。 这是我目前正在使用的数据: 我正在尝试在15分钟的时间内滚动显示此数据中的出现次数。该数据的预期结果如下: 样本数据: 我可以通过以下方式 使它 起作用: 但是,我想避免使用子查询,而建议使用(或其他任何可能的解决方案)解决方案。 这可能吗?还是子查询是正确的解决方案? 问题答案: 一种方法-如果表很大,可能比嵌

  • 问题内容: 如果我有三列: 我想计算一下表格中有多少唯一的电子邮件,我该怎么做? 如下语句: 给我总数。 我试过了 但这似乎并没有给我期望的数字。 问题答案: 采用 提供唯一的电子邮件ID,然后简单地对其进行计数。

  • 我正在使用Rest Assured API通过selenium自动化程序执行调用后操作 响应中大约有1000个或更多JSON对象。而且它们没有响应的标识符,比如“name”或“contractinfo” 我的质疑: 1.我如何检索数组的总数(如从''到'')使用Rest保证API结合JAVA和selenium? 请建议。 使用的图书馆─

  • 问题内容: 我有一个队列和一个同时进行出队和入队的函数。我想确保只要列表中有内容,队列中就可以使用适当数量的goroutine。 这是我正在使用的代码,但我想知道是否有一种方法可以打印当前活动的goroutine的数量 链接到游乐场 问题答案: 有,但是您正在解决这个错误。 您的循环将继续产生goroutine。 由于for循环,这将不必要地消耗cpu周期。 一种方法是使用sync.WaitGro

  • 问题内容: 假设我们有以下pandas DataFrame: 如何以 向量化的方式计算 大熊猫的连续数量?我想要这样的结果: 类似于矢量化求和运算的操作,它会在特定条件下重置。 问题答案: 您可以执行以下操作(贷方:如何使用系列/数据框模拟itertools.groupby):

  • 问题内容: 我正在寻找一种Python方式来计算正整数的二进制表示形式中的尾随零数(这将指示最大幂除而无余数)。 一个简单的解决方案: 但是,为了以更Python化的方式进行操作,我认为我可以利用: ,它给出的二进制表示形式 ,它给出了的反向二进制表示形式 因此,我的问题可以简化为对字符串中的尾随零进行计数。 有任何单一陈述的方式可以做到这一点吗? 我的最终目标是一种Python的方法,用于计算其