n个骰子的点数

n个骰子的点数

把n个骰子仍在地上,所有骰子朝上一面的点数之和为s。输入骰子个数n,求所有s出现的概率。

思路:假设f(m,n)表示投第m个骰子的时候,点数之和为n出现的次数,投第m个骰子的点数之和只与投第m-1个骰子有关。我们得到递归方程:

f(m,n)=f(m-1,n-1)+f(m-1,n-2)+f(m-1,n-3)+f(m-1,n-4)+f(m-1,n-5)+f(m-1,n-6)

表示本轮点数之和为n出现次数等于上一轮点数之和为n-1,n-2,n-3,n-4,n-5,n-6出现的次数之和。

动态规划参考代码:

root@gt:/home/git/Code# ./a.out 3 0.00462963
4 0.0138889
5 0.0277778
6 0.0462963
7 0.0694444
8 0.0972222
9 0.115741
10 0.125
11 0.125
12 0.115741
13 0.0972222
14 0.0694444
15 0.0462963
16 0.0277778
17 0.0138889
18 0.00462963
P:1
root@gt:/home/git/Code# cat shaizi.cpp #include <iostream> #include <math.h> using namespace std;
int g_max = 6;
void printProbability(int n)
{
    if(n < 1)
        return;
    int* pProbabilities[2];
    pProbabilities[0] = new int[g_max * n + 1];
    pProbabilities[1] = new int[g_max * n + 1];
    for(int i = 0;i < g_max * n + 1;++i)
    {
        pProbabilities[0][i] = 0;
        pProbabilities[1][i] = 0;
    }
    int flag = 0;
    for(int i = 1;i <= g_max;++i)
        pProbabilities[flag][i] = 1;
    for(int k = 2;k <= n;++k)
    {
        for(int i = 0;i < k;++i)
            pProbabilities[1-flag][i] = 0;
        for(int i = k;i <= g_max * k;++i)
        {
            pProbabilities[1 - flag][i] = 0;
            for(int j = 1;j <= i && j <= g_max;++j)
                pProbabilities[1 - flag][i] += pProbabilities[flag][i - j];
        }
        flag = 1 - flag;
    }

    double s ;
    double total = pow((double)g_max,n);
    for(int i = n;i <= g_max * n;++i)
    {
        double ratio = (double)pProbabilities[flag][i] / total;
        cout << i << " " << ratio << endl;
        s += ratio;
    }
    cout << "P:" << s << endl;
    delete[] pProbabilities[0];
    delete[] pProbabilities[1];
}

int main()
{
    printProbability(3);
    return 0;
}

    原文作者:ailx10
    原文地址: https://zhuanlan.zhihu.com/p/34698482
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞