[藍橋杯 2022 省 A] 爬樹的甲殼蟲

Gold_stein發表於2024-04-12

機率dp,關鍵是要走出思維定勢:

一般來講,都會把dp[i]定義為從0爬到高度i的機率,但是因為任何時刻都有掉下去的可能,這樣子不好推(也有大佬這樣做出來的)

我們把dp[i]定義為從i爬到n的機率,公式就好推了

而且,我們可以根據定義很自然地得到:

dp[n]=0

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

inline int read()
{
    int x = 0, f = 1; char ch = getchar();
    while(ch < '0' || ch > '9') 
    {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

const LL P = 998244353;

int n;

LL quick_pow(LL a, LL k)
{
    LL res = 1;
    while(k)
    {
        if(k&1) res = res*a%P;
        a = a * a % P;
        k>>=1;
    }
    return res;
}

int main()
{
    n = read();
    LL k1 = 1, k2 = 0, k3 = 0;
    for(int i = 1; i <= n; i++)
    {
        int a = read(), b = read();
        LL p_fall = 1ll*a*quick_pow(1ll*b, P-2) % P;
        LL p_up = 1ll*(b-a)*quick_pow(1ll*b, P-2) % P;
        k3 = (k3 + k1) % P;
        k2 = (k2 + p_fall * k1 % P) % P;
        k1 = (k1 * p_up) % P;
    }
    LL t = quick_pow(1ll-k2, P-2);
    t=(t%P+P)%P;
    printf("%lld",k3*t%P);
    return 0;
}

一開始過不了樣例,對著main函式看了半天,最後才發現問題在快速冪裡😂

一開始把

if(k&1) res = res*a%P;
        a = a * a % P;

這兩句的順序寫反了,先倍增a,然後才更新res,導致快速冪的結果錯誤

相關文章