60. n个骰子的点数

  • Post author:
  • Post category:其他




剑指 Offer 60. n个骰子的点数



n

个骰子扔在地上,所有骰子朝上一面的点数之和为

s

。输入

n

,打印出

s

的所有可能的值出现的概率。

你需要用一个浮点数数组返回答案,其中第

i

个元素代表这

n

个骰子所能掷出的点数集合中第

i

小的那个的概率。


示例 1:


输入:

1


输出:

[0.16667,0.16667,0.16667,0.16667,0.16667,0.16667]


示例 2:


输入:

2


输出:

[0.02778,0.05556,0.08333,0.11111,0.13889,0.16667,0.13889,0.11111,0.08333,0.05556,0.02778]


限制:


  • 1 <= n <= 11



解题思路

先解释一下题目的意思:



n

个骰子,总共出现的组合数应该有



6

n

6^n







6










n












种,而扔出的点数集合应该是

n ~ 6n

,共

(6n - n + 1)= 5n + 1

种可能。

比如扔一个骰子,则可能出现

6

种组合,点数是

1 ~ 6

。所以每个点数出现的概率是

[0.16667,0.16667,0.16667,0.16667,0.16667,0.16667]



而扔两个骰子时,可能出现的组合是



6

2

=

36

6^2 = 36







6










2











=








3


6





种组合,点数则是

2 ~ 12

,其中

2

只可能是两个骰子都出现

1

,

3

则一个骰子出现

1

,一个骰子出现

2

,共

2

种可能,后面的以此类推。除以

36

就是每个点数组合出现的概率。

这里我们可以用

动态规划

来做。

在这里插入图片描述



Java代码

class Solution {
    public double[] dicesProbability(int n) {
        //我们让骰子个数从1开始,故第一维为n+1,第二维表示的是点数,最大可6n,故6*n+1
        int[][] dp = new int[n + 1][6 * n + 1];

        //初始化dp,一个骰子扔出1~6点都只有一种可能
        for(int i = 1;i <= 6;i++) dp[1][i] = 1;

        for(int i = 1;i <= n;i++){//n个骰子
            for(int j = i;j <= 6*i;j++){//i个骰子最少可以扔出i点,最多6*i点
                for(int k = 1;k <= Math.min(j,6);k++){//保证j>=k
                    dp[i][j] += dp[i - 1][j - k];
                }
            }
        }

        double[] res = new double[5*n + 1];//6*n - n + 1种可能的点数集合
        for(int i = 0;i <= 5*n;i++){
            res[i] = dp[n][n+i] / (double)Math.pow(6,n);//转为double才能变为浮点除法
        }
        return res;
    }
}

在这里插入图片描述



版权声明:本文为YouMing_Li原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。