定义f[i][j]表示从(i,j)走到最后一行的期望,不断从下往上dp那么对于每一行都可以得到m个方程。
但由于这m个方程不是DAG,因此考虑用高斯消元,但时间复杂度不对。
观察方程可以发现如果不断将f[i][j]表示出f[i][j+1]并代入那么就可以计算出f[n][m],再不断反代出来即可。

1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mod 998244353 4 #define ll long long 5 ll n,m,a,b,x[1001],y[1001],f[1001]; 6 ll ksm(ll n,ll m){ 7 if (!m)return 1; 8 ll s=ksm(n,m>>1); 9 s=s*s%mod; 10 if (m&1)s=s*n%mod; 11 return s; 12 } 13 int main(){ 14 scanf("%lld%lld%lld%lld",&n,&m,&a,&b); 15 if (m==1){ 16 printf("%lld",2*(n-a)); 17 return 0; 18 } 19 for(int i=1;i<=n-a;i++){ 20 x[1]=(mod+1)/2; 21 y[1]=(f[1]+3)*x[1]%mod; 22 for(int j=2;j<m;j++){ 23 x[j]=(3LL*mod+1)/4; 24 y[j]=(1+x[j]*(f[j]+y[j-1]))%mod; 25 x[j]=ksm(x[j]*(3-x[j-1]+mod)%mod,mod-2); 26 y[j]=y[j]*x[j]%mod; 27 x[j]=x[j]*(3LL*mod+1)/4%mod; 28 } 29 f[m]=(y[m-1]+f[m]+3)*ksm((2-x[m-1]+mod)%mod,mod-2)%mod; 30 for(int j=m-1;j;j--)f[j]=(x[j]*f[j+1]+y[j])%mod; 31 } 32 printf("%lld",f[b]); 33 return 0; 34 }