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
}

 

posted on 2019-01-23 14:38  tianzeng  阅读(210)  评论(0编辑  收藏  举报

导航