【Analysis】
设
f
i
,
j
f_{i,j}
fi,j表示有
i
i
i个A,
j
j
j个AB期望长度。目标状态是
f
1
,
0
f_{1,0}
f1,0,因为
f
0
,
0
f_{0,0}
f0,0会转移自己。容易得到方程:
f
i
,
j
=
p
a
p
a
+
p
b
×
f
i
+
1
,
j
+
p
b
p
a
+
p
b
×
f
i
,
j
+
i
f_{i,j}= \dfrac{pa}{pa+pb} \times f_{i+1,j} + \dfrac{pb}{pa+pb}\times f_{i,j+i}
fi,j=pa+pbpa×fi+1,j+pa+pbpb×fi,j+i
初始转态是
f
i
,
j
(
i
+
j
⩾
k
)
f_{i,j}(i+j\geqslant k)
fi,j(i+j⩾k),因为再加一个B就完成了。设期望
x
x
x次中一次B,
P
a
←
p
a
p
a
+
p
b
P_a\gets\dfrac{pa}{pa+pb}
Pa←pa+pbpa,
P
b
←
p
b
p
a
+
p
b
P_b\gets\dfrac{pb}{pa+pb}
Pb←pa+pbpb,
c
←
i
+
j
c\gets i+j
c←i+j
x
←
P
b
×
∑
i
=
0
∞
(
c
+
i
)
×
P
a
i
x\gets P_b \times \sum\limits_{i=0}^{\infty}(c+i)\times P_a^i
x←Pb×i=0∑∞(c+i)×Pai
设数列
{
a
n
}
\{a_n\}
{an}满足
a
n
=
(
c
+
n
)
×
P
a
n
a_n=(c+n)\times P_a^n
an=(c+n)×Pan
设 S n = ∑ i = 0 n a i S_n=\sum\limits_{i=0}^na_i Sn=i=0∑nai
P a × S n = p a p a + p b × ∑ i = 0 n ( c + i ) × p a p a + p b P_a \times S_n=\dfrac{pa}{pa+pb}\times \sum\limits_{i=0}^n(c+i)\times \dfrac{pa}{pa+pb} Pa×Sn=pa+pbpa×i=0∑n(c+i)×pa+pbpa
= ∑ i = 0 n ( c + i ) × ( p a p a + p b ) i + 1 =\sum\limits_{i=0}^n(c+i)\times (\dfrac{pa}{pa+pb})^{i+1} =i=0∑n(c+i)×(pa+pbpa)i+1
∵ P a + P b = 1 \because P_a+P_b=1 ∵Pa+Pb=1
∴
x
←
lim
n
→
∞
P
b
×
S
n
=
lim
n
→
∞
S
n
−
P
a
×
S
n
\therefore x\gets \lim\limits_{n\to\infty}P_b\times S_n=\lim\limits_{n\to\infty}S_n-P_a\times S_n
∴x←n→∞limPb×Sn=n→∞limSn−Pa×Sn
=
lim
n
→
∞
∑
i
=
0
n
(
c
+
i
)
×
p
a
p
a
+
p
b
−
∑
i
=
0
n
(
c
+
i
)
×
(
p
a
p
a
+
p
b
)
i
+
1
=\lim\limits_{n\to\infty} \sum\limits_{i=0}^n(c+i)\times \dfrac{pa}{pa+pb}-\sum\limits_{i=0}^n(c+i)\times (\dfrac{pa}{pa+pb})^{i+1}
=n→∞limi=0∑n(c+i)×pa+pbpa−i=0∑n(c+i)×(pa+pbpa)i+1
=
lim
n
→
∞
(
c
+
0
)
×
P
a
0
+
∑
i
=
1
n
(
c
+
i
)
×
P
a
i
−
∑
i
=
1
n
(
c
+
i
−
1
)
×
P
a
i
+
(
c
+
n
)
×
P
a
n
+
1
=\lim\limits_{n\to\infty} (c+0)\times P_a^0 + \sum\limits_{i=1}^n(c+i)\times P_a^i-\sum\limits_{i=1}^n(c+i-1)\times P_a^i +(c+n)\times P_a^{n+1}
=n→∞lim(c+0)×Pa0+i=1∑n(c+i)×Pai−i=1∑n(c+i−1)×Pai+(c+n)×Pan+1
=
lim
n
→
∞
c
+
∑
i
=
1
n
P
a
i
+
(
c
+
n
)
×
P
a
n
+
1
=\lim\limits_{n\to\infty} c+\sum\limits_{i=1}^n P_a^i+(c+n)\times P_a^{n+1}
=n→∞limc+i=1∑nPai+(c+n)×Pan+1
=
lim
n
→
∞
c
+
P
a
−
P
a
n
×
P
a
1
−
P
a
+
(
c
+
n
)
×
P
a
n
+
1
=\lim\limits_{n\to\infty} c+\dfrac{P_a-P_a^n\times P_a}{1-P_a}+(c+n)\times P_a^{n+1}
=n→∞limc+1−PaPa−Pan×Pa+(c+n)×Pan+1
=
lim
n
→
∞
c
+
p
a
p
b
×
(
1
−
P
a
n
)
+
(
c
+
n
)
×
P
a
n
+
1
=\lim\limits_{n\to\infty} c+\dfrac{pa}{pb}\times (1-P_a^n)+(c+n)\times P_a^{n+1}
=n→∞limc+pbpa×(1−Pan)+(c+n)×Pan+1
=
lim
n
→
∞
c
+
p
a
p
b
+
(
c
+
n
)
×
P
a
n
+
1
=\lim\limits_{n\to\infty} c+\dfrac{pa}{pb}+(c+n)\times P_a^{n+1}
=n→∞limc+pbpa+(c+n)×Pan+1
=
lim
n
→
∞
c
+
p
a
p
b
+
c
+
n
(
p
a
+
p
b
p
a
)
n
+
1
=\lim\limits_{n\to\infty} c+\dfrac{pa}{pb}+\dfrac{c+n}{(\dfrac{pa+pb}{pa})^{n+1}}
=n→∞limc+pbpa+(papa+pb)n+1c+n
∵
(
c
+
n
)
随
着
n
的
增
大
单
调
递
增
,
(
p
a
+
p
b
p
a
)
n
+
1
随
着
n
的
增
大
单
调
递
增
\because (c+n)随着n的增大单调递增,(\dfrac{pa+pb}{pa})^{n+1}随着n的增大单调递增
∵(c+n)随着n的增大单调递增,(papa+pb)n+1随着n的增大单调递增
∴
满
足
洛
必
达
法
则
\therefore 满足洛必达法则
∴满足洛必达法则
根
据
洛
必
达
法
则
,
f
(
x
)
g
(
x
)
如
果
在
x
=
a
处
变
成
(
0
/
0
)
或
是
(
∞
/
∞
)
,
那
么
f
(
x
)
g
(
x
)
=
f
′
(
x
)
g
′
(
x
)
根据洛必达法则,\dfrac{f(x)}{g(x)}如果在x=a处变成 (0/0)或是(\infty/\infty),那么\dfrac{f(x)}{g(x)}=\dfrac{f^\prime(x)}{g^\prime(x)}
根据洛必达法则,g(x)f(x)如果在x=a处变成(0/0)或是(∞/∞),那么g(x)f(x)=g′(x)f′(x)
∴
x
←
lim
n
→
∞
c
+
p
a
p
b
+
c
+
n
(
p
a
+
p
b
p
a
)
n
+
1
\therefore x\gets \lim\limits_{n\to\infty} c+\dfrac{pa}{pb}+\dfrac{c+n}{(\dfrac{pa+pb}{pa})^{n+1}}
∴x←n→∞limc+pbpa+(papa+pb)n+1c+n
=
lim
n
→
∞
c
+
p
a
p
b
+
1
ln
(
p
a
+
p
b
p
a
)
×
(
p
a
+
p
b
p
a
)
n
+
1
=\lim\limits_{n\to\infty} c+\dfrac{pa}{pb}+\dfrac{1}{\ln(\dfrac{pa+pb}{pa})\times (\dfrac{pa+pb}{pa})^{n+1}}
=n→∞limc+pbpa+ln(papa+pb)×(papa+pb)n+11
=
c
+
p
a
p
b
=c+\dfrac{pa}{pb}
=c+pbpa
时间复杂度 Θ ( k 2 ) \Theta(k^2) Θ(k2)
【Code】
#include <bits/stdc++.h>
using namespace std;
typedef long long int64;
const int P = 1e9 + 7;
inline int qPow(int x, int y)
{
int res = 1, base = x;
while (y > 0)
{
if (y & 1)
res = 1ll * res * base % P;
base = 1ll * base * base % P;
y >>= 1;
}
return res;
}
inline int inv(int x) { return qPow(x, P - 2); }
inline int add(int x, int y) { x += y; x -= x >= P ? P : 0; return x; }
inline int mul(int x, int y) { return 1ll * x * y % P; }
int main(void)
{
int n = 1, a = 1, b = 1;
cin >> n >> a >> b;
const int A = 1ll * a * inv(a + b) % P;
const int B = (1 - A + P) % P;
const int V = 1ll * a * inv(b) % P;
vector <vector <int>> dp(n + 1);
for (int i = 1;i <= n; ++i)
dp[i].resize(n + 1);
for (int i = n;i >= 1; --i)
for (int j = n;j >= 0; --j)
dp[i][j] = (i + j >= n) ? (add(i, add(j, V))) : (add(mul(dp[i + 1][j], A), mul(dp[i][i + j], B)));
cout << dp[1][0] << '\n';
return 0;
}