AT2567 [ARC074C] RGB Sequence
https://www.luogu.com.cn/problem/AT2567
成功被降智
首先当前位置填3个颜色的方案数是一样的(等价的),所以不用管
考虑设 f [ i ] [ j ] [ k ] ( i > j > k ) f[i][j][k](i>j>k) f[i][j][k](i>j>k)表示考虑到当前第 i i i位,上一个和 i i i不同的在 j j j,剩下一个在 k k k的方案数
转移比较简单,考虑下一个颜色是是否和 i , j , k i,j,k i,j,k相同即可
对于它的限制,只需要在转移的时候不合法的丢掉就行了
是道不错的小清新dp题
code:
#include<bits/stdc++.h>
#define N 305
#define mod 1000000007
using namespace std;
void add(int &x, int y) { x += y;
if (x >= mod) x -= mod;
}
struct Q {
int l, r, x;
} q[N];
int cmp(Q x, Q y) {
return x.r < y.r;
}
int n, m, f[N][N][N];
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i ++) scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].x);
sort(q + 1, q + 1 + m, cmp);
f[1][0][0] = 3;
int pos = 1;
for(int i = 1; i <= n; i ++) {
while(pos <= m && q[pos].r <= i) {
for(int j = 0; j < i; j ++) {
for(int k = 0; k <= max(j - 1, 0); k ++) {
if(q[pos].x == 1 && j >= q[pos].l) f[i][j][k] = 0;
if(q[pos].x == 2 && (k >= q[pos].l || j < q[pos].l)) f[i][j][k] = 0;
if(q[pos].x == 3 && k < q[pos].l) f[i][j][k] = 0;
}
}
pos ++;
}
for(int j = 0; j < i; j ++)
for(int k = 0; k <= max(j - 1, 0); k ++) {
add(f[i + 1][j][k], f[i][j][k]);
add(f[i + 1][i][k], f[i][j][k]);
add(f[i + 1][i][j], f[i][j][k]);
}
}
int ans = 0;
for(int j = 0; j < n; j ++)
for(int k = 0; k <= max(j - 1, 0); k ++)
add(ans, f[n][j][k]);
printf("%d", ans);
return 0;
}