区间dp的题.
思路
可先用stake将每个位置的括号的匹配找出来,我们把他叫love数组
即
lovei=jlovej=i
l
o
v
e
i
=
j
l
o
v
e
j
=
i
(当然他们匹配)
我们可以开一个数组叫dp[i][j][0/1/2][0/1/2]
表示在左端点为i右端点为j左端点染了0/1/2右端点染了0/1/2时的方案数
分类讨论
- 当二者相邻,
dp[l][r][0][1]=dp[l][r][0][2]=dp[l][r][1][0]=dp[l][r][2][0]=1; d p [ l ] [ r ] [ 0 ] [ 1 ] = d p [ l ] [ r ] [ 0 ] [ 2 ] = d p [ l ] [ r ] [ 1 ] [ 0 ] = d p [ l ] [ r ] [ 2 ] [ 0 ] = 1 ;
- 否则,当二者匹配
for i=0,i−>2,i++for j=0,j−>2;j++if(i!=1)dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r−1][i][j]);if(j!=1)dp[l][r][0][1]=(dp[l][r][0][1]+dp[l+1][r−1][i][j]);if(j!=2)dp[l][r][0][2]=(dp[l][r][0][2]+dp[l+1][r−1][i][j]);if(i!=2)dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r−1][i][j]);
f
o
r
i
=
0
,
i
−
>
2
,
i
+
+
f
o
r
j
=
0
,
j
−
>
2
;
j
+
+
i
f
(
i
!
=
1
)
d
p
[
l
]
[
r
]
[
1
]
[
0
]
=
(
d
p
[
l
]
[
r
]
[
1
]
[
0
]
+
d
p
[
l
+
1
]
[
r
−
1
]
[
i
]
[
j
]
)
;
i
f
(
j
!
=
1
)
d
p
[
l
]
[
r
]
[
0
]
[
1
]
=
(
d
p
[
l
]
[
r
]
[
0
]
[
1
]
+
d
p
[
l
+
1
]
[
r
−
1
]
[
i
]
[
j
]
)
;
i
f
(
j
!
=
2
)
d
p
[
l
]
[
r
]
[
0
]
[
2
]
=
(
d
p
[
l
]
[
r
]
[
0
]
[
2
]
+
d
p
[
l
+
1
]
[
r
−
1
]
[
i
]
[
j
]
)
;
i
f
(
i
!
=
2
)
d
p
[
l
]
[
r
]
[
2
]
[
0
]
=
(
d
p
[
l
]
[
r
]
[
2
]
[
0
]
+
d
p
[
l
+
1
]
[
r
−
1
]
[
i
]
[
j
]
)
;
二者不匹配
for(LL i=0;i<=2;i++)
for(LL j=0;j<=2;j++)
for(LL k=0;k<=2;k++)
for(LL v=0;v<=2;v++)
{
if(!((k==1&&v==1)||(k==2&&v==2)))
dp[l][r][i][j]=((dp[l][loser][i][k]*dp[loser+1][r][v][j])%mod+dp[l][r][i][j]); for(LL i=0;i<=2;i++) for(LL j=0;j<=2;j++) for(LL k=0;k<=2;k++) for(LL v=0;v<=2;v++) { if(!((k==1&&v==1)||(k==2&&v==2))) dp[l][r][i][j]=((dp[l][loser][i][k]*dp[loser+1][r][v][j])%mod+dp[l][r][i][j]);然后dfs记忆化就行了.
#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL dp[744][744][3][3];
LL b[703];
LL love[703];
LL num=0;
const LL mod = 1000000007;
LL n;
void st()
{
stack<LL>s;
for(LL i=1;i<=n;i++)
{
if(b[i]==1) s.push(i);
else
{
love[s.top()]=i;
love[i]=s.top();
s.pop();
}
}
}
void dfs(LL l,LL r)
{
if(l==r-1)
{
dp[l][r][0][1]=dp[l][r][0][2]=dp[l][r][1][0]=dp[l][r][2][0]=1;
return;
}
if(love[l]==r)
{
dfs(l+1,r-1);
for(LL i=0;i<=2;i++)
for(LL j=0;j<=2;j++)
{
if(i!=1)
dp[l][r][1][0]=(dp[l][r][1][0]+dp[l+1][r-1][i][j])%mod;
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!=2)
dp[l][r][2][0]=(dp[l][r][2][0]+dp[l+1][r-1][i][j])%mod;
}
return;
}
else
{
LL loser=love[l];
dfs(l,loser);
dfs(loser+1,r);
for(LL i=0;i<=2;i++)
for(LL j=0;j<=2;j++)
for(LL k=0;k<=2;k++)
for(LL v=0;v<=2;v++)
{
if(!((k==1&&v==1)||(k==2&&v==2)))
dp[l][r][i][j]=((dp[l][loser][i][k]*dp[loser+1][r][v][j])%mod+dp[l][r][i][j])%mod;
}
return;
}
}
int main()
{
string a;
cin>>a;
for(LL i=0;i<a.size();i++)
{
if(a[i]=='(')
b[i+1]=1;
else
b[i+1]=0;
}
n=a.size();
st();
dfs(1,n);
LL ans=0;
for(LL i=0;i<=2;i++)
for(LL j=0;j<=2;j++)
{
ans+=dp[1][n][i][j]%mod;
ans%=mod;
}
cout<<ans;
}