#dp,vector#AT2567 [ARC074C] RGB Sequence
分析
一种很正常的想法就是设\(dp[i][j][k]\),
表示前\(i\)个格子,其它两种颜色出现的位置分别为\(j,k,j>k或j=k=0(可取两种颜色)\)的方案数
那么颜色种类限制可以开vector存下以右端点为关键字的限制,然后转移的时候
\(dp[i+1][i][j],dp[i+1][i][k],dp[i+1][j][k]\)都可以由判定过后的\(dp[i][j][k]\)转移
也就是选取不同的颜色转移,时间复杂度\(O(n^3)\),注意\(j=k=0\)的情况
代码
#include <cstdio>
#include <cctype>
#include <vector>
#define rr register
using namespace std;
const int mod=1000000007,N=301;
struct rec{int l,x;};
int dp[N][N][N],n,m,ans; vector<rec>K[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void Mo(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
inline signed check(int i,int j,int k){
for (rr int p=0;p<K[i].size();++p){
rr int l=K[i][p].l,x=K[i][p].x;
if (x!=(i>=l)+(j>=l)+(k>=l)) return dp[i][j][k]=0;
}
return dp[i][j][k];
}
signed main(){
n=iut(),m=iut(),dp[1][0][0]=3;
for (rr int i=1;i<=m;++i){
rr int l=iut(),r=iut(),x=iut();
K[r].push_back((rec){l,x});
}
for (rr int i=1;i<n;++i) for (rr int j=0;j<i;++j)
for (rr int k=0,t;k<j+(!k);++k) if (t=check(i,j,k))
Mo(dp[i+1][j][k],t),Mo(dp[i+1][i][j],t),Mo(dp[i+1][i][k],t);
for (rr int j=0,t;j<n;++j)
for (rr int k=0;k<j+(!k);++k)
if (t=check(n,j,k)) Mo(ans,t);
return !printf("%d\n",ans);
}