【hiho第174周】Dice Possibility

来源:互联网 发布:淘宝金丝绒裙子 编辑:程序博客网 时间:2024/06/06 06:38

时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
What is possibility of rolling N dice and the sum of the numbers equals to M?

输入
Two integers N and M. (1 ≤ N ≤ 100, 1 ≤ M ≤ 600)

输出
Output the possibility in percentage with 2 decimal places.
样例输入

2 10

样例输出

8.33

其实这题目与《剑指offer》上面试题43,由于之前看过这本书,我当场就撸了一个,依稀记得是用动态规划,通过

f[i][j]表示掷i次骰子,和为j的次数f[i][j]= 0;   j<if[i][j]=  f[i-1][j-1]         +f[i-1][j-2]         +f[i-1][j-3]         +f[i-1][j-4]         +f[i-1][j-5]         +f[i-1][j-6];   (j>=i)初始为f[1][j]=1其中j=1,2,3,4,5,6;最后直接除以6的i次方,即骰子的排列情况。大功告成

这个算法剑指offer上撸了2个一维数组即可完成
然而一直submit都不成功,现在想想,究其原因,应该是计算机遇到大数问题算不出来了。

于是采用了相同的思路,不过这时候

f[i][j]

表示的为掷i次骰子,和为j的概率,类型也改为double,由于

f[i-1][j-1]的时候,它只有1/6的可能在第i次掷到1,从而达到f[i][j]所以f[i][j]=  f[i-1][j-1]/6         +f[i-1][j-2]/6         +f[i-1][j-3]/6         +f[i-1][j-4]/6         +f[i-1][j-5]/6         +f[i-1][j-6]/6;   (j>=i)f[i][j]= 0;   j<i  (掷骰子i次和不可能低于i)初始条件也会改变初始为f[1][j]=1/6;其中j=1,2,3,4,5,6;

代码如下(Accept)

 #include <string.h> #include <math.h> #include <stdio.h>#include <iostream>#include <iomanip>using namespace std; int main() {     int i, j;    double *f[2];    cin >> i >> j;    f[0] = new double[6 * i + 1];    f[1] = new double[6 * i + 1];    bool flag = 0;    for (int k = 0; k<6 * i + 1; ++k)    {        f[0][k] = 0;        f[1][k] = 0;    }    for (int k = 1; k <= 6; ++k)    {        f[flag][k] = 1.0/6;    }    for (int k = 2; k <= i; ++k)    {        for (int u = 0; u<k; ++u)        {            f[1 - flag][u] = 0.0;        }        for (int u = k; u <= 6 * k; ++u)        {            f[1 - flag][u] = 0.0;            for (int p = 1; p <= u &&p <= 6; ++p)            {                f[1 - flag][u] += f[flag][u - p]/6;            }        }        flag = 1 - flag;    }    //double total = pow(6.0, i); 大数溢出了吧。。。    //double res = (double)f[flag][j] / total ;    printf("%.2f\n",f[flag][j]*100);    delete[] f[0];    delete[] f[1];    return 0;   }
原创粉丝点击