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;
}
posted @ 2021-10-15 09:19  lahlah  阅读(48)  评论(0编辑  收藏  举报