原题链接 cf 149D Coloring Brackets
voj题目链接 cf 149D Coloring Brackets
题目要求是 给一个完整的括号匹配序列,问总共有多少种涂色方案:涂色满足以下要求
1,每单个括号只能有三种情况,不涂色,涂红色和涂蓝色
2,每一对匹配的括号必须有且只有一个被涂色。
3,两个相邻的字符不能被涂相同 的颜色,
由于是对区间的涂色,可以考虑用区间dp,用 dp[i][j][k][t] 表示从i到j 区间被涂色后,i端涂的是k色,而j端涂的是t色。
渣渣代码,仅供参考:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 705
#define mod 1000000007
#define LL __int64
using namespace std;
LL dp[N][N][3][3];
char s[N];
int match[N];
void getmatch()
{
int stack[N];
int p=0;
int len=strlen(s);
for(int i=0; i<len; i++)
{
if(s[i]=='(')
stack[p++]=i;
else
{
match[i]=stack[p-1];
match[stack[p-1]]=i;
p--;
}
}
}
void dfs(int l,int r)
{
if(l+1==r)
{
dp[l][r][0][1]=1;
dp[l][r][1][0]=1;
dp[l][r][0][2]=1;
dp[l][r][2][0]=1;
return;
}
if(match[l]==r)
{
dfs(l+1,r-1);
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
{
if(j!=1)
dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r-1][i][j])%mod;
if(i!=1)
dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mod;
if(j!=2)
dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r-1][i][j])%mod;
if(i!=2)
dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r-1][i][j])%mod;
}
return;
}
else
{
int k=match[l];
dfs(l,k);
dfs(k+1,r);
for(int h=0; h<3; h++)
for(int t=0; t<3; t++)
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
if(!((i==1&&j==1)||(i==2&&j==2)))
dp[l][r][h][t]=(dp[l][r][h][t]+(dp[l][k][h][i]*dp[k+1][r][j][t])%mod)%mod;
}
}
int main()
{
// freopen("in.txt","r",stdin);
scanf("%s",s);
getmatch();
int len=strlen(s);
memset(dp,0,sizeof(dp));
dfs(0,len-1);
LL ans=0;
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
ans=(ans+dp[0][len-1][i][j])%mod;
printf("%I64d\n",ans);
return 0;
}