【dp】【概率与期望dp】骰子

【题目描述】  

骰子是一个六面分别刻有一到六点的立方体,每次投掷骰子,理论上得到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;
}

猜你喜欢

转载自blog.csdn.net/qq_42754826/article/details/89043168