[ABC275E] Sugoroku 4 题解

· · 题解

前言

这题生动地展现了飞行棋最后几步的经典画面,赛时瞎搞居然搞出来了。同学严重怀疑出题人飞行棋输多了才想到的这一题

解法

本题需要使用动态规划算法。

我们令 f_{i,j} 为第 i 轮转转盘的时候,走到格子 j 的概率(易得边界条件 f_{0,0}=1);令 s(x,y) 为从 x 格子开始,转盘转到了 y 后走到的格子,根据游戏规则有:

s(x,y)=\begin{cases}2n-x-y&x+y>n\\x+y &\operatorname{otherwise}\end{cases}

因为转盘转到 1M 的概率相同,所以易得:

除法时用乘法逆元求解即可,最终答案即为 $\sum\limits_{i=1}^Kf_{i,N}$。 放代码: ```cpp #include<bits/stdc++.h> #define int long long using namespace std; const int p=998244353; int n,f[1001][1001]; int qpow(int a,int b){ int r=1; while(b){ if(b&1)r=r%p*a%p; a=a%p*a%p; b>>=1; } return r; } int inv(int a,int b){ return a*qpow(b,p-2)%p; } // 逆元 int s(int x,int y){ return x+y>n?(n<<1ll)-x-y:x+y; } // 判断 x 走 y 步后会到哪 main(){ ios::sync_with_stdio(false); int m,k,c=0; cin>>n>>m>>k; f[0][0]=1; // 初始化 for(int i=1;i<=k;i++){ for(int j=0;j<n;j++) for(int r=1;r<=m;r++) (f[i][s(j,r)]+=inv(f[i-1][j],m))%=p; // 状态转移 (c+=f[i][n])%=p; // 求和 } cout<<c<<endl; return 0; } ```