算数学期望,每个人都可以分开来考虑。Xi表示第i个人跑到另外一边的次数。
Xi服从二项分布。概率的和是个二项式,(p+1-p)^T,把二项式展开,p的偶次项是留在原来那一边的概率。
可以用((a+b)^T+(a-b)^T)/2来算出偶次项之和。
也可以用矩阵快速幂。矩阵构造如下
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<stack> #include<vector> #include<map> #include<set> #include<algorithm> #include<cmath> //#include<bits/stdc++.h> using namespace std; typedef double MType; const int maxn = 1e5+5; struct Person { double p; char side; int T; void IN(){ scanf("%d %c %lf",&T,&side,&p); } void cal(MType &lft, MType &rgh){ double keep = (1+pow(1-2*p,T))/2; if(side == 'L') lft = keep, rgh = 1-keep; else lft = 1-keep, rgh = keep; } }P; //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif int N; scanf("%d",&N); MType L = 1, R = 0, ans = 0; for(int i = 0; i < N; i++){ P.IN(); MType l,r; P.cal(l,r); ans += L*l + R*r; L = r; R = l; } printf("%.12lf",ans); return 0; }
快速幂
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<stack> #include<vector> #include<map> #include<set> #include<algorithm> #include<cmath> //#include<bits/stdc++.h> using namespace std; const int MSIZE = 2, n = 2; typedef double MType; struct Matrix { MType dat[MSIZE][MSIZE]; MType *operator [](int x){ return dat[x]; } Matrix operator * (Matrix& B) { Matrix re; for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ re[i][j] = 0; for(int k = 0; k < n; k++){ re[i][j] += dat[i][k]*B[k][j]; } } } return re; } Matrix operator ^ (int q){ Matrix Re, A = *this; for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ Re[i][j] = i == j?1:0; } } while(q){ if(q&1){ Re = Re * A; } A = A * A; q >>= 1; } return Re; } }; const int maxn = 1e5+5; struct Person { double p; char side; int T; void IN(){ scanf("%d %c %lf",&T,&side,&p); } void cal(MType &lft, MType &rgh){ Matrix C; C[0][0] = C[1][1] = 1-p; C[0][1] = C[1][0] = p; C = C^T; if(side == 'L') lft = C[0][0], rgh = C[1][0]; else lft = C[0][1], rgh = C[1][1]; } }P[maxn]; //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif int N; scanf("%d",&N); for(int i = 0; i < N; i++){ P[i].IN(); } //sort(P,P+N); MType L = 1, R = 0, ans = 0; for(int i = 0; i < N; i++){ MType l,r; P[i].cal(l,r); ans += L*l + R*r; L = r; R = l; } printf("%.12lf",ans); return 0; }