【arc074e】RGB Sequence dp

Description

​ 丰泽爷今天也在愉快地玩Minecraft!

​ 现在丰泽爷有一块1∗N1∗N的空地,每个格子按照顺序标记为11到NN。丰泽爷想要在这块空地上铺上红石块、绿宝石块和钻石块作为装饰。每个格子只能选择一种方块。

​ 丰泽爷有自己的审美标准。他定下了MM条规定,每条规定形如(li,ri,xi)(li,ri,xi),表示闭区间[li,ri][li,ri]中,需要有恰好xixi种不同的方块。

​ 丰泽爷觉得这个任务实在是太简单了,于是把它交给了你,但是你发现有太多种方式可以满足丰泽爷的审美需求了!于是你希望先知道,一共有多少铺方块的方法,可以满足丰泽爷的审美需求?答案对109+7109+7取模

Input

​ 第一行两个整数,N,MN,M

​ 接下来MM行,每行三个整数li,ri,xili,ri,xi

Output

​ 一个整数,对109+7109+7取模后的答案

Sample Input

Case 1:
3 1
1 3 3

Case 2:
4 2
1 3 1
2 4 2

Case 3:
1 3
1 1 1
1 1 2
1 1 3

Case 4:
8 10
2 6 2
5 5 1
3 5 2
4 7 3
4 4 1
2 3 1
7 7 1
1 5 2
1 7 3
3 4 2

Sample Output

Case 1:
6

Case 2:
6

Case 3:
0

Case 4:
108

HINT

​ 1≤N,M≤3001≤N,M≤300

​ 1≤li≤ri≤N1≤li≤ri≤N

​ 1≤xi≤3

Sol

\(f[i][j][k]\)表示三种颜色最后一个出现位置时的方案数,我们把每个限制条件存到右端点中,每次暴力判断状态是否合法即可,不合法就置0,否则转移到下一位。

Code

#include <bits/stdc++.h>
using namespace std;
int f[305][305][305],n,m,ans,l,r,x;const int P=1e9+7;vector<pair<int,int> >v[305];
bool chk(int r,int g,int b)
{
    for(int t=max(r,max(g,b)),i=0;i<v[t].size();i++)
    {
        int l=v[t][i].first,x=v[t][i].second,tot=(r>=l)+(g>=l)+(b>=l);
        if(tot!=x) return 0;
    }
    return 1;
}
int main()
{
    scanf("%d%d",&n,&m);f[0][0][0]=1;
    for(int i=1;i<=m;i++) scanf("%d%d%d",&l,&r,&x),v[r].push_back(make_pair(l,x));
    for(int r=0;r<=n;r++) for(int g=0;g<=n;g++) for(int b=0;b<=n;b++)
    {
        if(!f[r][g][b]) continue;
        if(!chk(r,g,b)){f[r][g][b]=0;continue;}
        int t=max(r,max(g,b))+1;if(t==n+1) ans=(ans+f[r][g][b])%P;
        (f[t][g][b]+=f[r][g][b])%=P;(f[r][t][b]+=f[r][g][b])%=P;(f[r][g][t]+=f[r][g][b])%=P;
    }
    printf("%d\n",ans);
}

猜你喜欢

转载自www.cnblogs.com/CK6100LGEV2/p/9476209.html