Coloring Brackets
题意:一个只由小括号组成的字符串,对括号进行染色,且满足以下三点:
- Each bracket is either not colored any color, or is colored red, or is colored blue.
- 每个括号有三种选择:不染色,染成红色,染成蓝色;
- For any pair of matching brackets exactly one of them is colored. In other words, for any bracket the following is true: either it or the matching bracket that corresponds to it is colored.
- 每对匹配的括号有且仅有一个括号被染色;
- No two neighboring colored brackets have the same color.
- 相邻的括号不能染成同种颜色,但是可以都不染色;
思路:令dp[l][r][i][j]表示区间[l, r]中l, r分别染成i, j颜色(0<=i, j, <=2, 0表示不染色,1表示红色,2表示蓝色);
如果l和r是匹配的那么,
并且:
如果l和r不匹配,那么;
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
char s[710];
int match[710];
void Match(){
int len=strlen(s);
int pos[710], top=0;
for(int i=0; i<len; i++){
if(s[i]=='(') pos[top++]=i;
else{
if(top){
top--;
match[i]=pos[top];
match[pos[top]]=i;
}
else match[i]=-1;
}
}
}
ll dp[710][710][3][3];
void dfs(int l, int r){
if(l+1==r){
dp[l][r][0][1]=dp[l][r][0][2]=dp[l][r][1][0]=dp[l][r][2][0]=1;
return;
}
else 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(j!=2)
dp[l][r][0][2]=(dp[l][r][0][2]+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(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 i=0; i<3; i++){
for(int j=0; j<3; j++){
if((i==1&&j==1)||(i==2&&j==2)) continue;
dp[l][r][0][1]=(dp[l][r][0][1]+dp[l][k][0][i]*dp[k+1][r][j][1]%mod)%mod;
dp[l][r][0][2]=(dp[l][r][0][2]+dp[l][k][0][i]*dp[k+1][r][j][2]%mod)%mod;
dp[l][r][0][0]=(dp[l][r][0][0]+dp[l][k][0][i]*dp[k+1][r][j][0]%mod)%mod;
dp[l][r][1][0]=(dp[l][r][1][0]+dp[l][k][1][i]*dp[k+1][r][j][0]%mod)%mod;
dp[l][r][1][1]=(dp[l][r][1][1]+dp[l][k][1][i]*dp[k+1][r][j][1]%mod)%mod;
dp[l][r][1][2]=(dp[l][r][1][2]+dp[l][k][1][i]*dp[k+1][r][j][2]%mod)%mod;
dp[l][r][2][0]=(dp[l][r][2][0]+dp[l][k][2][i]*dp[k+1][r][j][0]%mod)%mod;
dp[l][r][2][1]=(dp[l][r][2][1]+dp[l][k][2][i]*dp[k+1][r][j][1]%mod)%mod;
dp[l][r][2][2]=(dp[l][r][2][2]+dp[l][k][2][i]*dp[k+1][r][j][2]%mod)%mod;
}
}
return;
}
}
int main(){
scanf("%s", s);
Match();
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("%lld\n", ans);
return 0;
}