【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);
}