csuoj2275-Left-Right-Win(概率期望)
题目大意
给出一张圆桌,其上有n个位置.给定向左和向右转移的概率 P l e f t P_{left} Pleft, P r i g h t P_{right} Pright.初始的判定点在0.在每一点判定点将进行判定,其将有 P l e f t P_{left} Pleft的概率将判定点左移一个位置,有 P r i g h t P_{right} Pright的概率右移一个位置,也有 1 − P l e f t − P r i g h t 1-P_{left}-P_{right} 1−Pleft−Pright的概率判中奖,并终止判定.判中奖的位置将得到100的奖励,问位置k的奖励的期望是多少?
解题思路
设位置i判为中奖的概率为dp[i]则可以列出转移方程:
d
p
[
i
]
=
P
l
e
f
t
∗
d
p
[
i
−
1
]
+
P
r
i
g
h
t
∗
d
p
[
(
i
+
1
)
%
n
]
dp[i]=P_{left}*dp[i-1]+P_{right}*dp[(i+1)\%n]
dp[i]=Pleft∗dp[i−1]+Pright∗dp[(i+1)%n]
设为等式一
而初始点的中奖概率为
d
p
[
0
]
=
P
l
e
f
t
∗
d
p
[
n
−
1
]
+
P
r
i
g
h
t
∗
d
p
[
1
]
+
(
1
−
P
l
r
f
t
−
P
r
i
g
h
t
)
dp[0]=P_{left}*dp[n-1]+P_{right}*dp[1]+(1-P_{lrft}-P_{right})
dp[0]=Pleft∗dp[n−1]+Pright∗dp[1]+(1−Plrft−Pright)
设为等式二
通过前面的式子我们可以发现,所有点的中奖概率都可以通过其他两个点的概率线性组合得到.将dp[0],dp[1]设为这个线性系的基底,则可以设下式:
d
p
[
i
]
=
c
[
i
]
∗
d
p
[
0
]
+
d
[
i
]
∗
d
p
[
1
]
dp[i]=c[i]*dp[0]+d[i]*dp[1]
dp[i]=c[i]∗dp[0]+d[i]∗dp[1]
设为等式三
进一步地,由等式一我们可以通过变换得到
d
p
[
i
+
1
]
=
(
1
/
P
r
i
g
h
t
)
∗
d
p
[
i
]
−
(
P
l
e
f
t
/
P
r
i
g
h
t
)
∗
d
p
[
i
−
1
]
dp[i+1]=(1/P_{right})*dp[i]-(P_{left}/P_{right})*dp[i-1]
dp[i+1]=(1/Pright)∗dp[i]−(Pleft/Pright)∗dp[i−1]
将等式三带入,则可以得到递推式
c
[
i
]
=
(
1
/
P
r
i
g
h
t
)
∗
c
[
i
−
1
]
−
(
P
l
e
f
t
/
P
r
i
g
h
t
)
∗
c
[
i
−
2
]
d
[
i
]
=
(
1
/
P
r
i
g
h
t
)
∗
d
[
i
−
1
]
−
(
P
l
e
f
t
/
P
r
i
g
h
t
)
∗
d
[
i
−
2
]
c[i]=(1/P_{right})*c[i-1]-(P_{left}/P_{right})*c[i-2]\\ d[i]=(1/P_{right})*d[i-1]-(P_{left}/P_{right})*d[i-2]
c[i]=(1/Pright)∗c[i−1]−(Pleft/Pright)∗c[i−2]d[i]=(1/Pright)∗d[i−1]−(Pleft/Pright)∗d[i−2]
其中c[0]=1,c[1]=0,d[0]=0,d[1]=1,故也就可以推出所有的c与d
而显然可以有
∑
i
=
0
n
−
1
d
p
[
i
]
=
1
\sum_{i=0}^{n-1}dp[i]=1
i=0∑n−1dp[i]=1
故有
(
∑
i
=
0
n
−
1
c
[
i
]
)
∗
d
p
[
0
]
+
(
∑
i
=
0
n
−
1
d
[
i
]
)
∗
d
p
[
1
]
=
1
(\sum_{i=0}^{n-1}c[i])*dp[0]+(\sum_{i=0}^{n-1}d[i])*dp[1]=1
(i=0∑n−1c[i])∗dp[0]+(i=0∑n−1d[i])∗dp[1]=1
设为等式四
而根据等式二,我们可以通过变换得到
(
1
−
P
l
e
f
t
∗
c
[
n
−
1
]
)
∗
d
p
[
0
]
+
(
P
l
e
f
t
∗
d
[
n
−
1
]
−
P
r
i
g
h
t
)
∗
d
p
[
1
]
=
1
−
P
l
e
f
t
−
P
r
i
g
h
t
(1-P_{left}*c[n-1])*dp[0]+(P_{left}*d[n-1]-P_{right})*dp[1]=1-P_{left}-P_{right}
(1−Pleft∗c[n−1])∗dp[0]+(Pleft∗d[n−1]−Pright)∗dp[1]=1−Pleft−Pright
设为等式五
联立等式四、五,则可以解出 d p [ 0 ] , d p [ 1 ] dp[0],dp[1] dp[0],dp[1]
而最终的答案也就是
d
p
[
k
]
=
c
[
k
]
∗
d
p
[
0
]
+
d
[
k
]
∗
d
p
[
1
]
dp[k]=c[k]*dp[0]+d[k]*dp[1]
dp[k]=c[k]∗dp[0]+d[k]∗dp[1]
AC代码
#include<bits/stdc++.h>
using namespace std;
double lpro,rpro;
double c[20],d[20];
double solve(int n,int k,double lpro,double rpro)
{
c[0]=1,c[1]=0;
d[0]=0,d[1]=1;
double sumc=1.0,sumd=1.0;
for(int i=2;i<n;i++)
{
c[i]=(1/rpro)*c[i-1]-(lpro/rpro)*c[i-2];
d[i]=(1/rpro)*d[i-1]-(lpro/rpro)*d[i-2];
sumc+=c[i],sumd+=d[i];
}
double a=1-lpro*c[n-1],b=-lpro*d[n-1]-rpro;
double e=sumc,f=sumd;
double s1=1-rpro-lpro;
double s2=1;
double dp0=(s1*f-s2*b)/(a*f-e*b);
double dp1=(s1*e-s2*a)/(b*e-f*a);
return c[k]*dp0+d[k]*dp1;
}
int main()
{
int t;
scanf("%d",&t);
for(int kace =1; kace <=t;kace++)
{
int no,n,k;
scanf("%d%d%d%lf%lf",&no,&n,&k,&lpro,&rpro);
printf("%d %.2f\n",kace ,100*solve(n,k,lpro,rpro));
}
}