蓝桥杯 爬树的甲壳虫

期望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倍以上了。

posted @ 2023-12-14 20:59  BakaCirno  阅读(61)  评论(0编辑  收藏  举报