-
题目描述:
-
把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S的所有可能的值出现的概率。
-
输入:
-
输入包括一个整数N(1<=N<=1000),代表有N个骰子。
-
输出:
-
可能有多组测试数据,对于每组数据,
按照Sample Output的格式输出每一个可能出现的和S的概率。
-
样例输入:
-
1 2
-
样例输出:
-
1: 0.167 2: 0.167 3: 0.167 4: 0.167 5: 0.167 6: 0.167 2: 0.028 3: 0.056 4: 0.083 5: 0.111 6: 0.139 7: 0.167 8: 0.139 9: 0.111 10: 0.083 11: 0.056 12: 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 1000
int 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
****************************************************************/