Blank
Problem Description
There are N blanks arranged in a row. The blanks are numbered 1,2,…,N from left to right.
Tom is filling each blank with one number in {0,1,2,3}. According to his thought, the following M conditions must all be satisfied. The ith condition is:
There are exactly xi different numbers among blanks ∈[li,ri].
In how many ways can the blanks be filled to satisfy all the conditions? Find the answer modulo 998244353.
Input
The first line of the input contains an integer T(1≤T≤15), denoting the number of test cases.
In each test case, there are two integers n(1≤n≤100) and m(0≤m≤100) in the first line, denoting the number of blanks and the number of conditions.
For the following m lines, each line contains three integers l,r and x, denoting a condition(1≤l≤r≤n, 1≤x≤4).
Output
For each testcase, output a single line containing an integer, denoting the number of ways to paint the blanks satisfying all the conditions modulo 998244353.
Sample Input
2 1 0 4 1 1 3 3
Sample Output
4 96
题意:就是有n长度的空位待你去填数,填的数的范围为0,1,2,3四种,但是有m个限制条件,每一限制条件代表L到R区间内恰有X个不同的数,问一共有多少种填数方案
题解:看了比赛题解才会做这道题,dp[i][j][k][l]表示前i个数中0,1,2,3最后一次出现的位置排序(降序)后为i,j,k,l的填数方案数
转换方程为分为四种情况:
1. 第i位出现的数和第i-1位出现的数一样,dp[i][j][k][l] += dp[i-1][j][k][l]
2.第i位出现的数和第j位出现的数一样,dp[i][i-1][k][l] += dp[i-1][j][k][l]
3.第i位出现的数和第k位出现的数一样,dp[i][i-1][j][l] += dp[i-1][j][k][l]
4.第i位出现的数和第l位出现的数一样,dp[i][i-1][j][k] += dp[i-1][j][k][l]
然后再计算dp的过程中,我们再加上限制条件,就能得到答案,具体看下面代码(C++会t,G++不会t)
看了标程,标程滚动了一维,优化了一下空间,但是不优化空间也过了,可能是数据的原因,下面就贴没有优化空间的代码,方便理解
//#include<bits/stdc++.h>
//#include<unordered_map>
//#include<unordered_set>
#include<iostream>
#include<sstream>
#include<iterator>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<set>
#include<vector>
#include<bitset>
#include<climits>
#include<queue>
#include<iomanip>
#include<cmath>
#include<stack>
#include<map>
#include<ctime>
#include<new>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define MT(a, b) memset(a,b,sizeof(a))
const int INF = 0x3f3f3f3f;
const int O = 1e6;
const int mod = 998244353;
const int maxn = 1e2 + 5;
const double PI = acos(-1.0);
const double E = 2.718281828459;
const double eps = 1e-8;
int dp[maxn][maxn][maxn][maxn];
vector< pair <int, int > >v[maxn];
void MOD( int &x ) { if(x >= mod) x -= mod;}
int main(){
int T; scanf("%d", &T);
while( T --) {
int n, m; scanf("%d%d", &n, &m);
for(int i=0; i<=n; i++) v[i].clear();
for(int i=0; i<m; i++) {
int L, R, X; scanf("%d%d%d", &L, &R, &X);
v[R].push_back( pair <int, int >(L, X) );
}
dp[0][0][0][0] = 1;
for(int i=1; i<=n; i ++) {
for(int j=0; j<=i; j++)
for(int k=0; k<=j; k++)
for(int l=0; l<=k; l++) dp[i][j][k][l] = 0;
for(int j=0; j<=i; j++)
for(int k=0; k<=j; k++)
for(int l=0; l<=k; l++){
MOD(dp[i][j][k][l] += dp[i-1][j][k][l]);
MOD(dp[i][i-1][k][l] += dp[i-1][j][k][l]);
MOD(dp[i][i-1][j][l] += dp[i-1][j][k][l]);
MOD(dp[i][i-1][j][k] += dp[i-1][j][k][l]);
}
if(v[i].size() == 0) continue;
for(int j=0; j<=i; j++)
for(int k=0; k<=j; k++)
for(int l=0; l<=k; l++)
for(int t=0; t<v[i].size(); t++) {
int L = v[i][t].first;
int X = v[i][t].second;
int cnt = 1 + (j >= L) + (k >= L) + (l >= L);
if(cnt != X) dp[i][j][k][l] = 0;
}
}
int ans = 0;
for(int j=0, i=n; j<=n; j++)
for(int k=0; k<=j; k++)
for(int l=0; l<=k; l++)
MOD(ans += dp[i][j][k][l]);
printf("%d\n", ans);
}
return 0;
}