题面如下:
思路 or 题解:
期望DP
状态转移[刷表法]:
D
P
[
i
]
[
j
]
i
:
表
示
第
i
轮
j
:
表
示
当
前
在
j
位
置
DP[i][j] \ \ \ i:表示第i轮 \ \ \ j:表示当前在j位置
DP[i][j] i:表示第i轮 j:表示当前在j位置
d
p
[
i
+
1
]
[
j
+
k
]
+
=
d
p
[
i
]
[
j
]
∗
1
m
(
j
+
k
≤
n
)
dp[i + 1][j + k] += dp[i][j] * \frac{1}{m} \ \ (j + k \le n)
dp[i+1][j+k]+=dp[i][j]∗m1 (j+k≤n)
d
p
[
i
+
1
]
[
2
n
−
j
−
k
]
+
=
d
p
[
i
]
[
j
]
∗
1
m
(
j
+
k
>
n
)
dp[i + 1][2n-j-k] += dp[i][j] * \frac{1}{m} \ \ (j + k > n)
dp[i+1][2n−j−k]+=dp[i][j]∗m1 (j+k>n)
注意 j ≠ n j \ne n j=n 因为当到停留在位置 n n n 的时候,已经胜利!就不存在后面的转移了。
AC代码:
#define int long long
//#define ll long long
#define PII pair<int, int>
#define px first
#define py second
typedef std::mt19937 Random_mt19937;
Random_mt19937 rnd(time(0));
using namespace std;
const int mod = 998244353;
const int N = 100009;
int ksm(int a, int b)
{
int ans = 1;
while (b)
{
if (b & 1)
ans = ans * a % mod;
b >>= 1;
a = a * a % mod;
}
return ans;
}
int dp[1009][1009];
int n, m, cnt;
void solve()
{
cin >> n >> m >> cnt;
int inv = ksm(m, mod - 2);
dp[0][0] = 1;
for (int i = 0; i <= cnt; i++)
for (int j = 0; j < n; j++)
for (int k = 1; k <= m; k++)
{
if (j + k <= n)
dp[i + 1][j + k] = (dp[i + 1][j + k] + dp[i][j] * inv) % mod;
else
dp[i + 1][2 * n - j - k] = (dp[i + 1][2 * n - j - k] + dp[i][j] * inv) % mod;
}
int ans = 0;
for (int i = 0; i <= cnt; i++)
ans = (ans + dp[i][n]) % mod;
cout << ans << '\n';
}
signed main()
{
buff;
solve();
}