题意:
给你一个正确的括号匹配序列。比如 (()) 只能是23匹配,14匹配。不能13,24。看了题解才知道。
每对匹配的括号中必须选一个进行涂色,蓝或红。
且相邻的括号颜色不能相同。问你涂色的方案数。
DP[x][y][i][j] ,i为1代表左端点x涂了蓝,2红,0无色。
j类似代表右端点。
#include <iostream>
#include <stdio.h>
#include <queue>
#include <string.h>
using namespace std;
#define LL long long
const LL maxn = 1e5+55;
const LL mod = 1e9+7;
char s[800];
LL len;
LL to[800];
LL dp[800][800][3][3];
void match()
{
LL a[800];
LL p=0;
for(LL i=1;i<=len;i++){
if(s[i]=='(') a[++p]=i;
else{
to[i]=a[p];
to[a[p]]=i;
p--;
}
}
for(LL i=1;i<=len;i++){
// printf("%d\n",to[i]);
}
}
void dfs(LL l,LL r)
{
if(l+1==r){
dp[l][r][0][1]=dp[l][r][1][0]=1LL;
dp[l][r][2][0]=dp[l][r][0][2]=1LL;
return;
}
if(to[l]==r){
dfs(l+1,r-1);
for(LL i=0;i<3;i++){
for(LL j=0;j<3;j++){
if(j!=1)
(dp[l][r][0][1]+=dp[l+1][r-1][i][j])%=mod;
if(j!=2)
(dp[l][r][0][2]+=dp[l+1][r-1][i][j])%=mod;
if(i!=1)
(dp[l][r][1][0]+=dp[l+1][r-1][i][j])%=mod;
if(i!=2)
(dp[l][r][2][0]+=dp[l+1][r-1][i][j])%=mod;
}
}
return;
}else{
dfs(l,to[l]);
dfs(to[l]+1,r);
// if(to[l]!=to[r]-1) while(1);
for(LL x = 0;x < 3;x++){
for(LL y = 0;y < 3;y++){
for(LL i = 0;i<3;i++){
for(LL j=0;j<3;j++){
if(i==0||j==0||i!=j)
(dp[l][r][x][y]+=dp[l][to[l]][x][i]*dp[to[l]+1][r][j][y]%mod)%=mod;
}
}
}
}
}
}
int main()
{
scanf("%s",s+1);
len = strlen(s+1);
match();
dfs(1,len);
LL ans = 0 ;
for(LL i =0 ;i<3;i++){
for(LL j=0;j<3;j++){
(ans+=dp[1][len][i][j])%=mod;
}
}
cout<<ans<<endl;
}