zoukankan      html  css  js  c++  java
  • 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;
        }
    };
    
  • 相关阅读:
    [转]几个开源的.net界面控件
    电脑上设置对眼睛友好的绿豆沙色
    [转] C# 绘制报表,使用Graphics.DrawString 方法
    Excel 绘制图表,如何显示横轴的数据范围
    [转] C#中绘制矢量图形
    Chapter 3 Protecting the Data(3):创建和使用数据库角色
    续x奇数倍(n+2*x)暴力算法是冠军的算法结合数量
    新秀学习SSH(十四)——Spring集装箱AOP其原理——动态代理
    中国是大数据的人工智能的发源地
    采用shell脚本统计代码的行数
  • 原文地址:https://www.cnblogs.com/libaoquan/p/7360331.html
Copyright © 2011-2022 走看看