蓝桥杯 爬树的甲壳虫
期望dp,但是过程是手推的
期望dp一般设置 \(f_n=0\),反推 \(f_0\),这样会容易理解一些
根据甲壳虫爬上一层有概率掉回第0层,得 \(f_i\):
\[f_i=1+p_{i+1}f_0+(1-p_{i+1})f_{i+1}
\]
令 \(i=0\),得:
\[\begin{aligned}
f_0=&p_1f_0+(1-p_1)f_1+1\\
=&p_1f_0+(1-p_1)[p_2f_0+(1-p_2)f_2+1]+1\\
=&p_1+p_2(1-p_1)f_0+(1-p_1)(1-p_2)f_2+1+(1-p_1)\\
=&[p_1+p_2(1-p_1)+p_3(1-p_1)(1-p_2)]f_0+(1-p_1)(1-p_2)(1-p_3)f_3+1+(1-p_1)+(1-p_1)(1-p_2)\\
...&\\
=&f_0\sum_{i=1}^np_i\prod_{j=1}^{i-1}(1-p_j)+f_n\prod_{i=1}^n(1-p_i)+1+\sum_{i=1}^{n-1}\prod_{j=1}^i(1-p_j)
\end{aligned}
\]
则:
\[f_0=\frac{\displaystyle{1+\sum_{i=1}^{n-1}\prod_{j=1}^i(1-p_j)}}{\displaystyle{1-\sum_{i=1}^np_i\prod_{j=1}^{i-1}(1-p_j)}}
\]
所以只需要预处理 \(\prod_{j=1}^i(1-p_j)\) 就可以了
N, mod = 100010, 998244353
n, a, b, p = 0, [0] * N, [0] * N, [0] * N
def qpow(x, k = mod - 2):
res = 1
while k > 0:
if k % 2 == 1: res = res * x % mod
x = x * x % mod
k //= 2
return res
def main():
global n
n = int(input())
for i in range(1, n + 1):
a[i], b[i] = map(int, input().split())
s = [0] * N
s[0] = 1
for i in range(1, 1 + n):
p[i] = a[i] * qpow(b[i])
s[i] = s[i - 1] * (1 - p[i] + mod) % mod
sum1, sum2 = 0, 0
for i in range(1, n): sum1 = (sum1 + s[i]) % mod
for i in range(1, n + 1): sum2 = (sum2 + p[i] * s[i - 1] % mod) % mod
ans = (1 + sum1) * qpow(1 - sum2 + mod) % mod
print(ans)
if __name__ == '__main__':
main()
不过说一句,python运行效率是真慢,慢出c++ 10倍以上了。