n 个骰子的点数
题目
把 n 个骰子扔在地上,所有骰子朝上一面的点数之和为 s。输入 n,打印出 s 的所有可能的值出现的概率。
package main import "math" func main() { var n int // dp[i][j] 就表示 投掷i次骰子后,点数j出现的次数 dp := make([][]int, n+1) for i := 1; i < n+1; i++ { dp[i] = make([]int, 6*n+1) } for i := 1; i <= 6; i++ { dp[1][i] = 1 } // 外层循环表示 i 个骰子 for i := 2; i <= n; i++ { // 内层循环表示总点数。i个骰子总点数至少为i,所以循环从i开始. i个骰子最大全是6 * i, 所以最大到 6 * i for j := i; j <= 6*i; j++ { // dp[i][j] 表示投掷 i 个骰子, 投掷出 j 点数的组合个数 // 而 i 个骰子点数 j, 可以由 i - 1个骰子,再加上一个骰子得来 // dp[i][j] = dp[i - 1][j - k] + dp[i - 1][j - 2] + ... + dp[i - 1][j - 6] // 换成for循环, 则如下代码 for k := 1; k <= 6; k++ { // k >= j时,表示 没有 dp[i - 1] + 1...6可组成 dp[i][j]. 直接break 退出循环 if k >= j { break } dp[i][j] += dp[i-1][j-k] } } } total := math.Pow(6, float64(n)) result := make([]float64, 6*n-n+1) for i := n; i <= 6*n; i++ { result[i-n] = float64(dp[n][i]) / total } return }