#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);
}
posted @ 2020-10-03 01:09  lemondinosaur  阅读(111)  评论(0编辑  收藏  举报