[ARC118E] Avoid Permutations 题解

[ARC118E] Avoid Permutations 题解

考虑容斥,当前路径经过了多少个障碍物,因为填 \(-1\) 的位置具体填什么未知,所以还需要记录目前没确定的 \(-1\) 的个数。

所以可以写出 状态表示 \(f_{i, j, k}\) 表示当前在 \((i, j)\),及之前 \(k\)\(-1\) 未确定。

因为转移的时候不知道下一个位置同行同列是否有障碍物,所以实际的状态还需要记录一下当前行/列有没有 \(-1\) 障碍物。

#include <algorithm>
#include <cstring>
#include <queue>
#include <set>
#include <iostream>
#define x first
#define y second
//#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 200 + 10, mod = 998244353;

int n, p[N], f[N][N][N][2][2], fac[N], m;
bool ok[N];

signed main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i ++) {
        cin >> p[i], m += p[i] == -1;
        if(p[i] != -1) ok[p[i]] = 1;
    }
    ok[0] = ok[n + 1] = 1;
    f[0][0][0][0][0] = 1;
    for(int i = 0; i <= n + 1; i ++) {
        for(int j = 0; j <= n + 1; j ++) {
            for(int k = 0; k <= m; k ++) {
                for(int ox = 0; ox < 2; ox ++) {
                    for(int oy = 0; oy < 2; oy ++) {
                        int v = f[i][j][k][ox][oy];
                        if(!v) continue;
                        (f[i + 1][j][k][0][oy] += v) %= mod;
                        (f[i][j + 1][k][ox][0] += v) %= mod;
                        if(!oy && p[i + 1] == -1 && !ok[j]) (f[i + 1][j][k + 1][1][1] -= v) %= mod;
                        if(!ox && p[i] == -1 && !ok[j + 1]) (f[i][j + 1][k + 1][1][1] -= v) %= mod; 
                        if(p[i + 1] > 0 && p[i + 1] == j) (f[i + 1][j][k][0][oy] -= v) %= mod;
                        if(p[i] > 0 && p[i] == j + 1) (f[i][j + 1][k][ox][0] -= v) %= mod; 
                        
//                        cout << i << ' ' << j << ' ' << k << ' ' << ox << ' ' << oy << ' ' << f[i][j][k][ox][oy] << '\n';
                    }
                } 
            }
        }
    }
    int ans = 0;
    fac[0] = 1;
    for(int i = 1; i <= m; i ++) fac[i] = 1ll * fac[i - 1] * i % mod;
    for(int k = 0; k <= m; k ++) {
        for(int x = 0; x < 2; x ++) {
            for(int y = 0; y < 2; y ++) {
                ans = (ans + 1ll * f[n + 1][n + 1][k][x][y] * fac[m - k] % mod) % mod;
            }
        }
    }
    cout << (ans + mod) % mod << '\n';
    
    return 0;
}
posted @ 2025-05-22 10:58  MoyouSayuki  阅读(17)  评论(0)    收藏  举报
:name :name