概率:如果你有一个m面,每个都有一个骰子,那就不可能获胜

时间:2013-01-06 13:39:01

标签: algorithm math probability

你会得到许多骰子,每个骰子都有许多面孔。你滚动所有的骰子并记下你掷出每个骰子所得到的所有投掷的总和。如果你得到一笔> = x,你就赢了,否则就输了。找出你获胜的概率。

我想过生成1到m(大小为n)的所有组合,并且只保留那些总和大于x的组合。方式总数是m ^ n

之后它只是两者的分歧。

有更好的方法吗?

3 个答案:

答案 0 :(得分:7)

[编辑:正如jpalacek所说,时间复杂性是错误的 - 我现在已经解决了这个问题。]

您可以通过动态编程更有效地解决这个问题,首先将其更改为问题:

我可以从n个骰子中获得至少x的多少种方式?

将其表示为f(x,n)。那一定是那个

f(x,n)= sum(f(x-i,n-1))对于所有1&lt; = i <= m。

即。如果第一个骰子有1个,剩下的n - 1个骰子必须加起来至少为x - 1;如果第一个骰子有2个,剩下的n - 1个骰子必须加起来至少为x - 2;等等。

总和中有m个术语,所以如果你memoise这个函数,它将是O(m ^ 2 * n ^ 2),因为它最多需要做这个求和工作(m * n)* n次(即每个唯一的函数输入集合一次,假设第一个参数x <= m * n)。

作为获得概率的最后一步,只需将f(x,n)的结果除以可能结果的总数,即m ^ n。

答案 1 :(得分:4)

只是为了加上@ j_random_hacker的基本正确答案,当你注意到

时,你可以更快

f(x,n)= f(x-1,n)-f(x-m-1,n-1)+ f(x-1,n-1)如果x> m + 1

这样,您只需花费O(1)时间计算每个f值。

答案 2 :(得分:1)

//传递curFace值将禁止重复组合
//对于3个骰子 - 和8 - 2 4 2和2 2 4是相同的组合 - 所以应该算作一个

int sums(int totSum,int noDices,int mFaces,int curFace,HashMap<String,Integer> map)
{

    int count=0;

    if (noDices<=0 || totSum<=0)
            return 0;

    if (noDices==1)
    {
         if (totSum>=1 & totSum<=mFaces)
             return 1;
         else
             return 0;    
    }
    if (map.containsKey(noDices+"-"+totSum))
        return map.get(noDices+"-"+totSum);

    for (int i=curFace;i<=mFaces;i++)
    {

        count+=sums(totSum-i,noDices-1,mFaces,i,map);
    }

    map.put(noDices+"-" +totSum,count);

    return count;
}