题目大意
![这里写图片描述](https://img-blog.csdn.net/20170401155427829?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2h1bmtpdGxhdQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
解题思路
Var[X]=E[(X−E[X])2]=E[X2+E[X]2−2∗X∗E[X]]=E[X2]−E[X]2
设F[i][j]表示第i次出现j的期望和。E[i][j]表示表示第i次出现j的概率和。G[i][j]表示第i次出现j的和的平方的期望。E,F的转移很好推,
G[i+1][k]+=(G[i][j]+2∗F[i][j]∗k+k∗k∗E[i][j])∗P[k]/(1−P[j]);
由于E[X^2]-E[X]^2的精度误差很大,我们考虑
Var[X]=E[(X−E[X])2]=E[(X−C−E[X−C])2]=E[(X−C−(E[X]−C))2]
我们发现这种变换是等价的,但是使E[X]^2变为零,这样就减少了精度误差。实践时只需将掷出的数减去E[X]/N即可。
code
using namespace std;
int const Mxn=1e5+9;
int N;LF P[9],E[Mxn][9],F[Mxn][9],G[Mxn][9];
int main(){
//freopen("dice.in","r",stdin);
//freopen("dice.out","w",stdout);
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
Fo(i,1,6)scanf("%lf",&P[i]);
scanf("%d",&N);
Fo(i,1,6)E[1][i]=P[i],F[1][i]=i*P[i],G[1][i]=i*i*P[i];
Fo(i,1,N-1)Fo(j,1,6)Fo(k,1,6)if(j!=k)
E[i+1][k]+=E[i][j]*P[k]/(1-P[j]),
F[i+1][k]+=(F[i][j]+k*E[i][j])*P[k]/(1-P[j]);
LF Ans1=0;
Fo(i,1,6)Ans1+=F[N][i];
printf("%.12lf\n",Ans1);Ans1/=N;
Fo(i,1,N)Fo(j,1,6)F[i][j]=G[i][j]=0;
Fo(i,1,6)F[1][i]=(i-Ans1)*P[i],G[1][i]=(i-Ans1)*(i-Ans1)*P[i];
Fo(i,1,N-1)Fo(j,1,6)Fo(k,1,6)if(j!=k)
F[i+1][k]+=(F[i][j]+(k-Ans1)*E[i][j])*P[k]/(1-P[j]),
G[i+1][k]+=(G[i][j]+2*F[i][j]*(k-Ans1)+(k-Ans1)*(k-Ans1)*E[i][j])*P[k]/(1-P[j]);
LF Ans2=0;
Fo(i,1,6)Ans2+=G[N][i];
printf("%.12lf",Ans2);
return 0;
}