lintcode-20-骰子求和

20-骰子求和

扔 n 个骰子,向上面的数字之和为 S。给定 Given n,请列出所有可能的 S 值及其相应的概率。

注意事项

You do not care about the accuracy of the result, we will help you to output results.

样例

给定 n = 1,返回 [ [1, 0.17], [2, 0.17], [3, 0.17], [4, 0.17], [5, 0.17], [6, 0.17]]。

标签

数学 动态规划 概率

思路

利用动态规划,用二维数组 dp[i][j] 表示 i 颗骰子所能掷出点数为 j 的次数。

  • 初始时只有一颗骰子,此时 dp[1][j] = 0,(1 <= j <= 6)
  • 加一颗骰子后,此时 2 颗骰子所能掷出的点数为 2 到 12,此时投掷的结果与上一次投掷的结果相关,若 2 颗骰子投出 j 点,则要求第 1 颗投掷投出 k 点且第 2 颗投出 j - k 点(j > k) ,例如 dp[2][2] = dp[1][1],dp[2][3] = dp[1][1] + dp[1][2]...
  • 一般化,加至第 i 颗骰子后,此时 i 颗骰子所能掷出的点数为 i 到 6 * 1,此时投掷的结果与前 i - 1次投掷的结果相关,若 i 颗骰子投出 j 点,则要求前 i - 1 颗投掷投出 k 点且第 2 颗投出 j - k点(j > k) ,即 dp[i][j] = dp[i-1][j-1] + dp[i-1][j-2] + dp[i-1][j-3] + dp[i-1][j-4] + dp[i-1][j-5] + dp[i-1][j-6]

最后某点的次数除以总数,即投掷出此点的概率。

code

class Solution {
public:
    /**
     * @param n an integer
     * @return a list of pair<sum, probability>
     */
    vector<pair<int, double>> dicesSum(int n) {
        // Write your code here
        if (n <= 0) {
            return vector<pair<int, double> >();
        }

        long long total = powOf6(n);
        vector<vector<long long>> dp(n + 1, vector<long long>(6 * n + 1, 0));
        dp[1][1] = 1;
        dp[1][2] = 1;
        dp[1][3] = 1;
        dp[1][4] = 1;
        dp[1][5] = 1;
        dp[1][6] = 1;
        for (int i = 2; i <= n; i++) {
            for (int j = i; j <= i * 6; j++) {
                long x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 = 0;
                if (j - 1 > 0) {
                    x1 = dp[i - 1][j - 1];
                }
                if (j - 2 > 0) {
                    x2 = dp[i - 1][j - 2];
                }
                if (j - 3 > 0) {
                    x3 = dp[i - 1][j - 3];
                }
                if (j - 4 > 0) {
                    x4 = dp[i - 1][j - 4];
                }
                if (j - 5 > 0) {
                    x5 = dp[i - 1][j - 5];
                }
                if (j - 6 > 0) {
                    x6 = dp[i - 1][j - 6];
                }
                dp[i][j] = x1 + x2 + x3 + x4 + x5 + x6;
            }
        }
        vector<pair<int, double> > result;
        for (int i = n; i <= 6 * n; i++) {
            pair<int, double> p(i, double(dp[n][i]) / total);
            result.push_back(p);
        }
        return result;
    }

    long long powOf6(int n) {
        long long sum = 1;
        for (int i = 0; i<n; i++) {
            sum *= 6;
        }
        return sum;
    }
};
posted @ 2017-08-14 21:33  LiBaoquan  阅读(579)  评论(0编辑  收藏  举报