目录
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−1个骰子的解f(n - 1),此时添加一枚骰子,求n个骰子的点数和为x的概率f(n, x)。
当添加骰子的点数为1时,前n−1个骰子的点数和应为x−1,方可组成点数和x;
同理,当此骰子为2时,前n−1个骰子应为x−2;
以此类推,直至此骰子点数为6。将这6种情况的概率相加,即可得到概率f(n,x)。
递推公式如下所示:
但是这个递推式会造成x-i越界的问题,比如x=2时,i若大于2均无意义,所以我们可以反向求解,概率仅与有关系,所以我们遍历中各点数和的概率,然后将其加至对应的中的相关项,即可完成递推。
class Solution {
public double[] dicesProbability(int n) {
double[] dp=new double[6];
Arrays.fill(dp,1.0/6.0);//初始化dp数组,当一个骰子时出现的点数及概率
for (int i = 2; i <= n; i++) {//从两个骰子开始遍历
double[] temp=new double[5*i+1];//当有i个骰子时,就有5i+1种可能
for (int j = 0; j < dp.length ; j++) {//遍历每种骰子和的可能
for (int k = 0; k < 6; k++) {//将当前的概率加入到i+1个骰子的情况
temp[j+k]+=dp[j]/6.0;
}
}
dp=temp;
}
return dp;
}
}