【数学】骰子问题
骰子问题
问题描述:
众所周知,骰子是一个六面分别刻有1到6点的立方体,每次投掷骰子,从理论上讲得到1点到6点的概率都是1/6。今有骰子一颗,连续投掷n次,问点数总和大于x的概率是多少?
输入格式:
仅有一行,包含两个用空格隔开的整数,分别表示n和x,其中1<=n<=24,0<=x<150。
输出格式:
输出文件仅有一行,为一个分数。要求以最简的形式精确地表达出连续投掷n次骰子,总点数大于等于x的概率。
输入:
3 9
输出:
20/27
试题分析:
好,现在我告诉你分数原型是160/216,你是否明白了呢?
没错,216就是6^3,因为每一次扔骰子可以有1~6任意一种,
那么和(不考虑重复的)就为6^3
这是总的种数,那么160是什么呢?
就是满足大于等于X的方法数(方法数也不考虑重复)
那么就可以设F(i,j)为要组成等于i,扔j次骰子的方法种数
可以得到,我们可以循环加上去的1~6(k),再循环现在的数字(j)
那么可以得到F(i,j)=sum(F(k+j,i+1)) (0≤i<N,0≤j≤i*6,0<l<7)
代码如下(压位不会啊QAQ):
#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long
using namespace std;
LL f[1001][1001];
LL N,X;
LL tmp=1;
LL ans;
long long Gcd(LL a,LL b){//最大公约数
if(b==0) return a;
return Gcd(b,a%b);
}
int main(){
cin>>N>>X;
f[0][0]=1;
for(LL i=0;i<N;i++){
tmp*=6;//(216)
for(LL j=0;j<=i*6;j++)//枚举现在的数字
for(LL k=1;k<=6;k++)
f[k+j][i+1]+=f[j][i];
}
for(LL i=X;i<=6*N;i++) ans+=f[i][N];//(ans=160),加上符合条件的方法数
LL K=Gcd(ans,tmp);
ans/=K,tmp/=K;//约分
if(tmp==1) cout<<1;
else cout<<ans<<"/"<<tmp;
}
你——悟到了么?

浙公网安备 33010602011771号