機率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,導致快速冪的結果錯誤