剑指 Offer 60. n个骰子的点数
dp三步走:
1.表示状态
dp[i][j]表示掷i个骰子,点数之和为j的概率。
2.状态转移方程
递推公式dp[i][j]=dp[i-1][j-1]+……+dp[i-1][j-6]
i个骰子和为j的概率 = i-1个骰子和为j-1 * 最后一个骰子掷出1的概率 +……+ i-1个骰子和为j-6 * 最后一个骰子掷出6的概率
3.边界处理
i=1时,概率均为1/6
剑指 Offer 60. n个骰子的点数
class Solution { public double[] dicesProbability(int n) { //dp[i][j]表示掷i个骰子,点数之和为j的概率 double[][] dp = new double[n + 1][6 * n + 1]; //边界问题,掷1个骰子得到1-6概率均为6分之一 for(int i = 1; i <= 6; i++) dp[1][i] = (double)1 / 6; //从掷两个骰子开始递推 for(int i = 2; i <= n; i++) //i个骰子点数之和的范围是i~6*i for(int j = i; j <= 6 * i; j++) //递推公式dp[i][j]=dp[i-1][j-1]+……+dp[i-1][j-6] //i个骰子和为j的概率 = i-1个骰子和为j-1 * 最后一个骰子掷出1的概率+……+i-1个骰子和为j-6 * 最后一个骰子掷出6的概率 for(int k = 1; k <= 6; k++){ //边界问题,下面的j-k不能越界 if(j - k <= 0) continue; dp[i][j] += dp[i - 1][j - k] / 6; } //一共能掷出5*n+1个点数和 double[] res = new double[5 * n + 1]; int sum = n; //在循环赋值中写sum++,可以合并成1句 for(int i = 0; i < res.length; i++) res[i] = dp[n][sum++]; return res; } }