九度OJ 1255:骰子点数概率 (递归、DP)

来源:互联网 发布:mac下制作winpe启动盘 编辑:程序博客网 时间:2024/05/21 11:37

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:316

解决:29

题目描述:

把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S的所有可能的值出现的概率。

输入:

输入包括一个整数N(1<=N<=1000),代表有N个骰子。

输出:

可能有多组测试数据,对于每组数据,
按照Sample Output的格式输出每一个可能出现的和S的概率。

样例输入:
12
样例输出:
1: 0.1672: 0.1673: 0.1674: 0.1675: 0.1676: 0.1672: 0.0283: 0.0564: 0.0835: 0.1116: 0.1397: 0.1678: 0.1399: 0.11110: 0.08311: 0.05612: 0.028

思路:

标准的动态规划题目,根据上一步状态推出下一步。

另外此题判题数据应该是错误的,比如别人能AC的程序输入4得到的结果是:

4: 0.002
5: 0.005
6: 0.009
7: 0.017
8: 0.028
9: 0.043
10: 0.062
11: 0.080
12: 0.096
13: 0.108
14: 0.113
15: 0.108
16: 0.096
17: 0.080
18: 0.062
19: 0.043
20: 0.027
21: 0.015
22: 0.008
23: 0.003
24: 0.001


4和24对应的概率不一样,这显然是是错误的。

下面分别给出能AC的代码和我的代码。


代码1(能AC的代码):

#include<stdio.h> #include<string.h> #include<math.h> int main() {     int n,i,j,k;     double a[2][6005],all;     while(scanf("%d",&n)!=EOF)     {         memset(a,0,sizeof(a));         a[1][1]=1;         a[1][2]=1;         a[1][3]=1;         a[1][4]=1;         a[1][5]=1;         a[1][6]=1;         for(i=2;i<=n;i++)         {             for(j=i*6;j>=i;j--)             {                 a[i%2][j]=0;                 if(j-1>0)                     a[i%2][j]+=a[(i+1)%2][j-1];                 if(j-2>0)                     a[i%2][j]+=a[(i+1)%2][j-2];                 if(j-3>0)                     a[i%2][j]+=a[(i+1)%2][j-3];                 if(j-4>0)                     a[i%2][j]+=a[(i+1)%2][j-4];                 if(j-5>0)                     a[i%2][j]+=a[(i+1)%2][j-5];                 if(j-6>0)                     a[i%2][j]+=a[(i+1)%2][j-6];             }         }         all=pow(6.0,n);         for(i=n;i<=n*6;i++)             printf("%d: %.3lf\n",i,a[n%2][i]/all);         printf("\n");     }     return 0; }


代码2(我的代码):

#include <stdio.h>#define N 1000int main(void){    int n, i, j, k;    double a[2][N*6];    while (scanf("%d", &n) != EOF)    {        a[0][0] = 1;        for(i=1; i<=n; i++)        {            for (j=i; j<=i*6; j++)            {                a[i&1][j] = 0;                for (k=j-1; k>=j-6; k--)                {                    if (k>=i-1 && k<=(i-1)*6)                        a[i&1][j] += a[(i-1)&1][k]/6;                }                if (i == n)                    printf("%d: %.3lf\n", j, a[i&1][j]);            }        }        printf("\n");    }    return 0;}
/**************************************************************    Problem: 1255    User: liangrx06    Language: C    Result: Wrong Answer****************************************************************/



1 0