結果

問題 No.3071 Double Speedrun
ユーザー 👑 seekworser
提出日時 2025-02-07 14:09:07
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 752 ms / 6,000 ms
コード長 1,077 bytes
コンパイル時間 3,672 ms
コンパイル使用メモリ 283,052 KB
実行使用メモリ 6,820 KB
最終ジャッジ日時 2025-02-08 01:39:28
合計ジャッジ時間 9,927 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 14
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
#include <atcoder/modint>
using namespace std;
using mint = atcoder::modint998244353;

int main() {
    int h,w; cin >> h >> w;
    vector<string> s(h);
    for (int i=0; i<h; i++) cin >> s[i];
    vector dp(h, vector<mint>(h, mint(0)));
    dp[0][0] = 1;
    // dp[i][j][k]: i列目まで決めて、Bobがその列で到達した最大の行がj、Aliceがその行で到達した最小の行がk
    // 遷移は累積和を用いて高速化可能、O(H^2W)
    for (int i=1; i<w; i++) {
        for (int j=0; j<h; j++) for (int k=0; k<h-1; k++) {
            if (s[k+1][i-1] == '#' || dp[j][k].val() == 0) continue;
            dp[j][k+1] += dp[j][k];
        }
        vector dpn(h, vector<mint>(h, mint(0)));
        for (int j=0; j<h; j++) for (int k=j+1; k<h; k++) {
            if (s[j][i] == '#' || s[k][i] == '#') continue;
            if (j > 0 && dpn[j-1][k].val() != 0) dpn[j][k] += dpn[j-1][k];
            if (dp[j][k].val() != 0) dpn[j][k] += dp[j][k];
        }
        swap(dp, dpn);
    }
    cout << dp[h-2][h-1].val() << '\n';
}
0