题目:
https://codeforces.ml/problemset/problem/908/D
有一个字符串,初始为空,每次随机添加 a a a或 b b b,当子序列为 a b ab ab的个数大于等于 k k k时停止。求最终得到的子序列 a b ab ab的个数的期望。
思路:
设
f
(
i
,
j
)
f(i,j)
f(i,j)表示从字符串有
i
i
i个
a
a
a,
j
j
j个
a
b
ab
ab时的状态,到最终态(即
a
b
ab
ab的个数大于等于
k
k
k)的期望个数(期望
d
p
dp
dp的套路,反着
d
p
dp
dp),有
p
a
p_a
pa概率添加a,同理
p
b
p_b
pb,
p
a
+
p
b
=
1
p_a+p_b=1
pa+pb=1则有
f
(
i
,
j
)
=
p
a
∗
f
(
i
+
1
,
j
)
+
p
b
∗
(
i
,
j
+
i
)
f(i,j)=p_a*f(i+1,j)+p_b*(i,j+i)\\
f(i,j)=pa∗f(i+1,j)+pb∗(i,j+i)
解释就是
i
i
i个
a
a
a,
j
j
j个
a
b
ab
ab时的状态,添加
a
a
a就会到达
i
+
1
i+1
i+1个
a
a
a,
j
j
j个
a
b
ab
ab时的状态,添加
b
b
b就会到达
i
i
i个
a
a
a,
i
+
j
i+j
i+j个
a
b
ab
ab时的状态。答案就是
f
(
0
,
0
)
f(0,0)
f(0,0)。
现在考虑初始值
- 当
j
≥
k
j\ge k
j≥k时
f ( i , j ) = j f(i,j)=j f(i,j)=j
因为已经结束了,得到的 a b ab ab一定是 j j j个。但这样还不够,比如 f ( 0 , 0 ) f(0,0) f(0,0)和 f ( 1 , 0 ) f(1,0) f(1,0)有关, f ( 1 , 0 ) f(1,0) f(1,0)和 f ( 2 , 0 ) f(2,0) f(2,0)有关,一直到 f ( ∞ , 0 ) f(\infty,0) f(∞,0)。 - 当
i
+
j
≥
k
,
j
<
k
i+j\ge k,j<k
i+j≥k,j<k时,再添加
x
(
0
≤
x
≤
∞
)
x(0\le x\le \infty)
x(0≤x≤∞)个连续的
a
a
a,然后在添加一个
b
b
b就能结束状态,最后得到
i
+
j
+
x
i+j+x
i+j+x个
a
b
ab
ab,所以有
f ( i , j ) = ∑ x = 0 ∞ p a x p b ( i + j + x ) = ( i + j ) p b ∑ x = 0 ∞ p a x + p b ∑ x = 0 ∞ x p a x ( p a ∞ = 0 ) = ( i + j ) p b 1 1 − p a + p b ∑ x = 0 ∞ x p a x \begin{aligned} f(i,j)&=\sum_{x=0}^{\infty}p_a^xp_b(i+j+x)\\ &=(i+j)p_b\sum_{x=0}^{\infty}p_a^x+p_b\sum_{x=0}^{\infty}xp_a^x\quad (p_a^{\infty}=0)\\ &=(i+j)p_b\frac{1}{1-pa}+p_b\sum_{x=0}^{\infty}xp_a^x\\ \end{aligned} f(i,j)=x=0∑∞paxpb(i+j+x)=(i+j)pbx=0∑∞pax+pbx=0∑∞xpax(pa∞=0)=(i+j)pb1−pa1+pbx=0∑∞xpax
∑ x = 0 ∞ x p a x = 1 p a 1 + 2 p a 2 + 3 p a 3 + . . . + ∞ p a ∞ = ( p a 1 + p a 2 + p a 3 + . . . p a ∞ ) + ( p a 2 + p a 3 + . . . p a ∞ ) + ( p a 3 + . . . p a ∞ ) = ∑ i = 1 ∞ ∑ j = i ∞ p a j = p a ( 1 − p a ) 2 \begin{aligned} \sum_{x=0}^{\infty}xp_a^x&=1p_a^1+2p_a^2+3p_a^3+...+\infty p_a^{\infty}\\ &=(p_a^1+p_a^2+p_a^3+...p_a^{\infty})+(p_a^2+p_a^3+...p_a^{\infty})+(p_a^3+...p_a^{\infty})\\ &=\sum_{i=1}^{\infty}\sum_{j=i}^{\infty}p_a^j\\ &=\frac{p_a}{(1-p_a)^2} \end{aligned} x=0∑∞xpax=1pa1+2pa2+3pa3+...+∞pa∞=(pa1+pa2+pa3+...pa∞)+(pa2+pa3+...pa∞)+(pa3+...pa∞)=i=1∑∞j=i∑∞paj=(1−pa)2pa
所以
f ( i , j ) = i + j + p a p b f(i,j)=i+j+\frac{p_a}{p_b}\\ f(i,j)=i+j+pbpa
所以要从 f ( 0 , 0 ) f(0,0) f(0,0)递归 d p dp dp计算,因为初始值有无穷多,没法从初始状态推。
#include<cstdio>
#include<cstring>
const int MAXK=1005,MOD=1000000007;
int pow_mod(int a,int b)
{
int res=1;
while(b)
{
if(b&1)
res=(1LL*res*a)%MOD;
b>>=1;
a=(1LL*a*a)%MOD;
}
return res;
}
int inv(int x)
{return pow_mod(x,MOD-2);}
int dp[MAXK][MAXK];
int k,pa,pb;
int DP(int i,int j)
{
if(j>=k)
return j;
if(i+j>=k)
return (i+j+1LL*pa*inv(pb)%MOD)%MOD;
if(dp[i][j]!=-1)
return dp[i][j];
return dp[i][j]=(1LL*((1LL*pa*DP(i+1,j))%MOD+(1LL*pb*DP(i,i+j))%MOD)*inv(pa+pb))%MOD;
}
int main()
{
scanf("%d%d%d",&k,&pa,&pb);
memset(dp,-1,sizeof dp);
printf("%d\n",DP(1,0));
return 0;
}