有三个面数不同的骰子,每次得分为三个骰子的点数和,但当三个骰子的点数满足某个条件时,分数会清0,问分数大于N需要投掷次数的期望。
典型的期望题,但是有环。论文中说这种题一般用高斯消元通解,但是这一题比较特殊,所有的环都是回到0点,所以可以将每个点的期望化简到一个关于E[0]的线性方程租,然后求系数即可。
1 /* 2 设E[x]为x分时到达n分的期望投掷次数,pk为掷到k分的概率,p0为回到0分的概率 3 有E[x]=∑E[x+k]*pk+p0*E[0]+1 4 假设E[x]=A[x]*E[0]+B[x] 5 则 E[x]= ∑(A[x+k]*E[0]+B[x+k])*p[k]+p0*E[0]+1 6 =(∑(A[x+k]*pk)+p0)*E[0]+∑B[x+k]*pk+1 7 即有A[x]=∑A[x+k]*pk+p0,B[x]=∑B[x+k]*pk+1 8 当x>n时A[x]=B[X]=0,从后向前可以求出A[0],E[0]=B[0]/(1-A[0]) 9 */ 10 #include <stdio.h> 11 #include <string.h> 12 int cas,n,k1,k2,k3,a,b,c; 13 double p[20],full; 14 double A[502],B[502]; 15 int main(){ 16 scanf("%d",&cas); 17 while(cas--){ 18 scanf("%d%d%d%d%d%d%d",&n,&k1,&k2,&k3,&a,&b,&c); 19 full=k1*k2*k3; 20 memset(p,0,sizeof p); 21 for(int i=1;i<=k1;i++) 22 for(int j=1;j<=k2;j++) 23 for(int k=1;k<=k3;k++) 24 if(i!=a||j!=b||k!=c) 25 p[i+j+k]+=1/full; 26 p[0]=1/full; 27 memset(A,0,sizeof A);memset(B,0,sizeof B); 28 for(int i=n;i>=0;i--){ 29 A[i]=p[0],B[i]=1; 30 for(int j=1;j<=k1+k2+k3;j++){ 31 A[i]+=A[i+j]*p[j],B[i]+=B[i+j]*p[j]; 32 } 33 } 34 printf("%.16f\n",B[0]/(1-A[0])); 35 } 36 return 0; 37 }