Description
Solution
原题只要保留6位小数,
记录每个人走j步到达终点的概率,当j足够大时就可以满足进精度要求,
证明一下为什么这样可行:
我们走很多步依旧没有到达终点的概率很小,而走这么多步还依旧赢的概率更小,所以对答案的影响很小,
Code
#include <cstdio>
#include <algorithm>
#include <iostream>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
#define efo(i,q) for(int i=A[q];i;i=B[i][0])
#define min(q,w) ((q)>(w)?(w):(q))
#define max(q,w) ((q)<(w)?(w):(q))
using namespace std;
typedef double db;
const int N=152,M=600000;
int read(int &n)
{
char ch=' ';int q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int m,n;
db ans;
int a[N],b[N];
db f[2][N];
db f1[22][M+2];
db g[22][M+2],g1[M+2];
int main()
{
freopen("feixingqi.in","r",stdin);
freopen("feixingqi.out","w",stdout);
int q,w;
read(n),read(m);
if(m==1)return printf("1.000000\n"),0;
fo(i,1,n)read(a[i]);
fo(i,1,m)read(b[i]);
f[0][n]=1;
fo(j,1,M)
{
int I=j&1,I1=!I;
db t=f[I1][n]*6;
f[I][n]=0;
fod(i,n-1,n-6)
{
f[I][i]=t*0.16666666666666666666666666666666666666666666666666666667;
t+=f[I1][a[i]]-f[I1][a[n]];
}
fod(i,n-7,1)
{
f[I][i]=t*0.16666666666666666666666666666666666666666666666666666667;
t+=f[I1][a[i]]-f[I1][a[i+6]];
}
fo(i,1,m)f1[i][j]=f[I][b[i]];
}
fo(i,0,M)g[m+1][i]=1;
fod(i,m,1)fod(j,M,0)
{
f1[i][j]+=f1[i][j+1];
g[i][j]=f1[i][j]*g[i+1][j];
}
fo(i,0,M)g1[i]=1;
fo(i,1,m)
{
ans=0;
fo(j,0,M)
{
ans+=(g1[j]*g[i+1][j])*(f1[i][j]-f1[i][j+1]);
g1[j]*=f1[i][j+1];
}
printf("%.6lf\n",ans);
}
return 0;
}