[AT2567] [arc074_c] RGB Sequence
题目链接
AtCoder:https://arc074.contest.atcoder.jp/tasks/arc074_c
洛谷:https://www.luogu.org/problemnew/show/AT2567
Solution
这算是\(\rm AtCoder\)里非常清新的一道题了...
不难想到设\(f[i][r][g][b]\)表示当前\(dp\)到第\(i\)位,最后一个红色在\(r\)位置,\(g,b\)同理。
可以注意到\(\max(r,g,b)=i\),所以可以省掉第一维。
那么去掉不合法情况之后直接暴力转移就好了,复杂度\(O(n^3)\)。
#include<bits/stdc++.h>
using namespace std;
void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}
#define lf double
#define ll long long
#define pii pair<int,int >
#define vec vector<pii >
#define pb push_back
#define mp make_pair
#define fr first
#define sc second
const int maxn = 302;
const int inf = 1e9;
const lf eps = 1e-8;
const int mod = 1e9+7;
int f[maxn][maxn][maxn],n,m;
vec s[maxn];
void add(int &x,int y) {x+=y;if(x>mod) x-=mod;}
int check(int r,int g,int b) {
int now=max(r,max(g,b));
for(int i=0,L=s[now].size()-1;i<=L;i++) {
int l=s[now][i].fr,x=s[now][i].sc;
int p=(r>=l)+(g>=l)+(b>=l);
if(p!=x) return 1;
}return 0;
}
int main() {
read(n),read(m);
for(int i=1,l,r,x;i<=m;i++) read(l),read(r),read(x),s[r].pb(mp(l,x));
f[0][0][0]=1;int ans=0;
for(int r=0;r<=n;r++)
for(int g=0;g<=n;g++)
for(int b=0;b<=n;b++) {
if((r==g||r==b||g==b)&&((!r)+(!g)+(!b))<2) continue;
if(check(r,g,b)) continue;
int k=max(r,max(g,b))+1;
add(f[k][g][b],f[r][g][b]);
add(f[r][k][b],f[r][g][b]);
add(f[r][g][k],f[r][g][b]);
if(k==n+1) add(ans,f[r][g][b]);
}write(ans);
return 0;
}