dp[ o ][ i ][ j ][ k ]
表示前 o 个已经填完, 不同数字的最后一个分别在o, i, j, k, 直接dp, 把限制丢到R, 在R转移出去的时候把不合法的丢掉。
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() #define fio ios::sync_with_stdio(false); cin.tie(0); using namespace std; const int N = 100 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;} template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;} int n, m; int dp[2][N][N][N]; int (*f)[N][N] = dp[0]; int (*g)[N][N] = dp[1]; int T; vector<PII> V[N]; void init(int n) { for(int i = 0; i < n; i++) { for(int j = 0; j <= i; j++) { for(int k = 0; k <= j; k++) { f[i][j][k] = 0; } } } } int main() { scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { V[i].clear(); } for(int i = 1; i <= m; i++) { int l, r, x; scanf("%d%d%d", &l, &r, &x); V[r].push_back(mk(l, x)); } init(1); f[0][0][0] = 4; bool judge; for(int o = 1; o < n; o++) { swap(f, g); init(o + 1); for(int i = 0; i < o; i++) { for(int j = 0; j <= i; j++) { for(int k = 0; k <= j; k++) { if(!g[i][j][k]) continue; judge = true; for(auto &t : V[o]) { if(t.se == 1) { if(i >= t.fi) { judge = false; break; } } else if(t.se == 2) { if(i < t.fi || j >= t.fi) { judge = false; break; } } else if(t.se == 3) { if(j < t.fi || k >= t.fi) { judge = false; break; } } else { if(k < t.fi) { judge = false; break; } } } if(judge) { add(f[i][j][k], g[i][j][k]); add(f[o][i][j], g[i][j][k]); add(f[o][i][k], g[i][j][k]); add(f[o][j][k], g[i][j][k]); } } } } } int ans = 0; for(int i = 0; i < n; i++) { for(int j = 0; j <= i; j++) { for(int k = 0; k <= j; k++) { if(!dp[i][j][k]) continue; judge = true; for(auto &t : V[n]) { if(t.se == 1) { if(i >= t.fi) { judge = false; break; } } else if(t.se == 2) { if(i < t.fi || j >= t.fi) { judge = false; break; } } else if(t.se == 3) { if(j < t.fi || k >= t.fi) { judge = false; break; } } else { if(k < t.fi) { judge = false; break; } } } if(judge) { add(ans, f[i][j][k]); } } } } printf("%d ", ans); } return 0; } /* */