[AT2567] [arc074_c] RGB Sequence

题目链接

AtCoder:https://arc074.contest.atcoder.jp/tasks/arc074_c

洛谷:https://www.luogu.org/problemnew/show/AT2567

Solution

这算是( m 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('
');}

#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;
}
原文地址:https://www.cnblogs.com/hbyer/p/10725912.html