题意:给你一个完整的括号匹配让你涂色,涂色的条件是
一个括号必须涂一边,而且只能涂一边。相邻的颜色不能相同而且只能涂蓝色和红色,然后求涂色方案数
题解:用思维然后dp[l][r][lc][rc]表示我此时涂的是第l到第r个括号边,lc表示之前左边涂的颜色,rc表示之前右边涂的颜色,0表示没涂,1表示涂蓝,2表示涂红色
然后判断l和r是在同一个括号,两个相邻的括号,两个括号不相邻的这些情况怎么转移一下即可
#include<iostream>
#include<cstring>
#include<cstdio>
#include<stack>
#include<algorithm>
using namespace std;
typedef long long int ll;
const int mod = 1e9+7;
const int mx = 705;
ll dp[mx][mx][3][3];
char s[mx];
int p[mx];
stack<int>st;
ll dfs(int l,int r,int lc,int rc){
if(l>=r) return 1;
if(dp[l][r][lc][rc]!=-1) return dp[l][r][lc][rc];
int x = p[l];
int y = p[r];
dp[l][r][lc][rc] = 0;
if(x==r){
for(int i = 1; i <= 2; i++)
if(i!=rc)
dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,r-1,0,i))%mod;
for(int i = 1; i <= 2; i++)
if(i!=lc)
dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,r-1,i,0))%mod;
}
else if(x+1==y){
for(int i = 1; i <= 2; i++)
for(int j = 1; j <= 2; j++)
if(i!=lc&&j!=rc)
dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,i,0)*dfs(y+1,r-1,0,j))%mod;
for(int i = 1; i<= 2; i++)
for(int j = 1; j <= 2; j++)
if(i!=j)
dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,0,i)*dfs(y+1,r-1,j,0))%mod;
for(int i = 1; i <= 2; i++)
for(int j = 1; j <= 2; j++)
if(i!=lc)
dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,i,0)*dfs(y+1,r-1,j,0))%mod;
for(int i = 1; i <= 2; i++)
for(int j = 1; j <= 2; j++)
if(j!=rc)
dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,0,i)*dfs(y+1,r-1,0,j))%mod;
}
else{
for(int i = 1; i <= 2; i++)
for(int j = 1; j <= 2; j++)
if(i!=lc&&j!=rc)
dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,i,0)*dfs(x+1,y-1,0,0)%mod*dfs(y+1,r-1,0,j))%mod;
for(int i = 1; i<= 2; i++)
for(int j = 1; j <= 2; j++)
dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,0,i)*dfs(x+1,y-1,i,j)%mod*dfs(y+1,r-1,j,0))%mod;
for(int i = 1; i <= 2; i++)
for(int j = 1; j <= 2; j++)
if(i!=lc)
dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,i,0)*dfs(x+1,y-1,0,j)%mod*dfs(y+1,r-1,j,0))%mod;
for(int i = 1; i <= 2; i++)
for(int j = 1; j <= 2; j++)
if(j!=rc)
dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,0,i)*dfs(x+1,y-1,i,0)%mod*dfs(y+1,r-1,0,j))%mod;
}
// cout<<dp[l][r][lc][rc]<<endl;;
return dp[l][r][lc][rc];
}
int main(){
memset(dp,-1,sizeof(dp));
int n;
scanf("%s",s+1);
n = strlen(s+1);
for(int i = 1; i <= n; i++)
if(s[i]=='(')
st.push(i);
else{
p[st.top()] = i;
p[i] = st.top();
st.pop();
}
ll ans = dfs(1,n,0,0);
printf("%I64d\n",ans);
return 0;
}