E - Sugoroku 4(期望DP)[AtCoder Beginner Contest 275]

题面如下:

在这里插入图片描述
题目链接

思路 or 题解:

期望DP
状态转移[刷表法]:
D P [ i ] [ j ]     i : 表 示 第 i 轮     j : 表 示 当 前 在 j 位 置 DP[i][j] \ \ \ i:表示第i轮 \ \ \ j:表示当前在j位置 DP[i][j]   ii   jj
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+kn)
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][2njk]+=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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Joanh_Lan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值