【题目描述】
骰子是一个六面分别刻有一到六点的立方体,每次投掷骰子,理论上得到1到6的概率都是1/6
有骰子一颗,连续投掷n次,问点数总和大于等于X的概率是多少
【输入】
输入一行2个证书,分别表示n,X,其中1<=N<=24,0<=X<150
【输出】
1行,一个分数,要求用最简的形式精确的表达投掷n次骰子,总数大于等于x的概率。如果是0/1,则输出0,如果1/1输出1
【样例输入】
3 9
【样例输出】
20/27
分析:
模拟投掷过程,从投掷一次开始,将可能的点数不断累加,最后再除以每个点数的总和,即为每个点数出现的概率
• 设f[i][j]表示投掷i次,点数为j的次数
• f[0][0]=1
• f[i][j]=sum{f[i-1][j-k]}(1<=k<=6)
• f[n][x~6*n]/total即为答案
• total表示每个点数的可能总数=6^n
• 可以用滚动数组优化空间
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,x,f[30][200],tot,ans;
int main(){
scanf("%lld%lld",&n,&x);
tot=pow(6,n);
f[0][0]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=150;j++){
for(int k=1;k<=6;k++)
if(j-k>=0)f[i][j]+=f[i-1][j-k];
}
}
for(int i=x;i<=6*n;i++)
ans+=f[n][i];
ll g=__gcd(ans,tot);
ans/=g;tot/=g;
if(ans==0) puts("0");
else if(tot==1) printf("%lld",ans);
else printf("%lld/%lld",ans,tot);
return 0;
}