题意
给定三个数
k
k
,,
pb
p
b
每次有
papa+pb
p
a
p
a
+
p
b
的概率往后面添加一个’
a
a
’
每次有的概率往后面添加一个’
b
b
’
当出现了个形如
ab
a
b
的子序列(不用连续)时停止
求最后的
ab
a
b
序列的期望数
答案对
109+7
10
9
+
7
取膜
Sol
f[i][j]
f
[
i
]
[
j
]
表示前面有
i
i
个,
j
j
对的期望
ab
a
b
的对数
倒着来转移
显然
f[i][j]=f[i+1][j]∗papa+pb+f[i][i+j]∗pbpa+pb
f
[
i
]
[
j
]
=
f
[
i
+
1
]
[
j
]
∗
p
a
p
a
+
p
b
+
f
[
i
]
[
i
+
j
]
∗
p
b
p
a
+
p
b
答案就是
f[0][0]
f
[
0
]
[
0
]
辣
然而
f[0][0]=f[1][0]∗papa+pb+f[0][0]∗pbpa+pb
f
[
0
]
[
0
]
=
f
[
1
]
[
0
]
∗
p
a
p
a
+
p
b
+
f
[
0
]
[
0
]
∗
p
b
p
a
+
p
b
不好算
移项后得到
f[0][0]=f[1][0]
f
[
0
]
[
0
]
=
f
[
1
]
[
0
]
所以输出
f[1][0]
f
[
1
]
[
0
]
就好了
然而串长是无限的,
a
a
的个数也是无限的,的对数无限,它们可以到
∞
∞
这就很不好做了了
但是你会发现,当
a
a
无穷多时,放一个,
ab
a
b
对数就会超过
k
k
,显然直接就停了
对于,当
i+j>=k
i
+
j
>=
k
时,考虑它的期望
也就是
f[i][j]=pbpa+pb∑∞l=0(papa+pb)l(i+j+l)
f
[
i
]
[
j
]
=
p
b
p
a
+
p
b
∑
l
=
0
∞
(
p
a
p
a
+
p
b
)
l
(
i
+
j
+
l
)
设
S=∑∞l=0(papa+pb)l(i+j+l)
S
=
∑
l
=
0
∞
(
p
a
p
a
+
p
b
)
l
(
i
+
j
+
l
)
则
papa+pbS=∑∞l=0(papa+pb)l+1(i+j+l)
p
a
p
a
+
p
b
S
=
∑
l
=
0
∞
(
p
a
p
a
+
p
b
)
l
+
1
(
i
+
j
+
l
)
两式相减得
(1−papa+pb)S=(i+j)+∑∞l=1(papa+pb)l
(
1
−
p
a
p
a
+
p
b
)
S
=
(
i
+
j
)
+
∑
l
=
1
∞
(
p
a
p
a
+
p
b
)
l
而
∑∞l=1(papa+pb)l
∑
l
=
1
∞
(
p
a
p
a
+
p
b
)
l
也可以类似处理
得到就是
papa+pb−(papa+pb)∞1−papa+pb=papb
p
a
p
a
+
p
b
−
(
p
a
p
a
+
p
b
)
∞
1
−
p
a
p
a
+
p
b
=
p
a
p
b
带回去
(1−papa+pb)S=(i+j)+papb
(
1
−
p
a
p
a
+
p
b
)
S
=
(
i
+
j
)
+
p
a
p
b
即
pbpa+pbS=(i+j)+papb
p
b
p
a
+
p
b
S
=
(
i
+
j
)
+
p
a
p
b
所以
f[i][j]=pbpa+pbS=(i+j)+papb
f
[
i
]
[
j
]
=
p
b
p
a
+
p
b
S
=
(
i
+
j
)
+
p
a
p
b
# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int Zsy(1e9 + 7);
int k, pa, pb, invb, inv, f[1005][1005], Pa, Pb;
IL int Input(){
RG int x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
}
IL int Pow(RG ll x, RG ll y){
RG ll ret = 1;
for(; y; y >>= 1, x = x * x % Zsy)
if(y & 1) ret = ret * x % Zsy;
return ret;
}
int main(RG int argc, RG char *argv[]){
k = Input(), pa = Input(), pb = Input();
invb = Pow(pb, Zsy - 2), inv = Pow(pa + pb, Zsy - 2);
Pa = 1LL * pa * inv % Zsy, Pb = 1LL * pb * inv % Zsy;
for(RG int i = k; i; --i)
for(RG int j = k; ~j; --j)
if(i + j >= k) f[i][j] = ((i + j) + 1LL * pa * invb % Zsy + Zsy) % Zsy;
else f[i][j] = (1LL * f[i + 1][j] * Pa % Zsy + 1LL * f[i][j + i] * Pb % Zsy) % Zsy;
printf("%d\n", f[1][0]);
return 0;
}