解析:
这道题主要难在情况有点多,稍微思路不清晰就会GG。
这里借鉴了一下这位大佬的分析:CF 149D Coloring Brackets
题目大意:
给一个给定括号序列,给该括号上色,上色有三个要求
1、只有三种上色方案,不上色,上红色,上蓝色
2、每对括号必须只能给其中的一个上色
3、相邻的两个不能上同色,可以都不上色
求这一区间内有多少种上色方案,很明显的区间DP
]表示区间两端颜色分别是i,j的方案数
0代表不上色,1代表上红色,2代表上蓝色
对于区间,有3种情况:
1、如果 说明就只有一对,那么
2、如果与是配对的
递归
状态转移
3、如果与不配对
代码:
#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
const int Max=705;
int n,m,tot,pos,p[Max];
long long ans;
long long f[Max][Max][3][3];
char ch[Max];
inline void pre()
{
n=strlen(ch+1);
for(int i=1;i<=n-1;i++)
{
if(ch[i]==')') continue;
int sum=0;
for(int j=i+1;j<=n;j++)
{
if(ch[j]=='(') sum++;
else sum--;
if(sum==-1) {p[i]=j,p[j]=i;break;}
}
}
}
inline void solve(int l,int r)
{
if(l+1==r)
{
f[l][r][0][1]=1;
f[l][r][1][0]=1;
f[l][r][0][2]=1;
f[l][r][2][0]=1;
return;
}
if(p[l]==r)
{
solve(l+1,r-1);
for(int i=0;i<=2;i++)
for(int j=0;j<=2;j++)
{
if(j!=1) f[l][r][0][1]=(f[l][r][0][1]+f[l+1][r-1][i][j])%mod;
if(i!=1) f[l][r][1][0]=(f[l][r][1][0]+f[l+1][r-1][i][j])%mod;
if(j!=2) f[l][r][0][2]=(f[l][r][0][2]+f[l+1][r-1][i][j])%mod;
if(i!=2) f[l][r][2][0]=(f[l][r][2][0]+f[l+1][r-1][i][j])%mod;
}
}
else
{
solve(l,p[l]),solve(p[l]+1,r);
for(int i=0;i<=2;i++)
for(int j=0;j<=2;j++)
for(int k=0;k<=2;k++)
for(int q=0;q<=2;q++)
{
if(k==q&&k&&q) continue;
f[l][r][i][j]=(f[l][r][i][j]+f[l][p[l]][i][k]*f[p[l]+1][r][q][j]%mod)%mod;
}
}
}
int main()
{
scanf("%s",ch+1);
pre();
solve(1,n);
for(int i=0;i<=2;i++)
for(int j=0;j<=2;j++)
ans=(ans+f[1][n][i][j])%mod;
cout<<ans;
return 0;
}