区间dp好题cf149d 括号匹配
见题解链接https://blog.csdn.net/sdjzping/article/details/19160013
#include<bits/stdc++.h> using namespace std; #define maxn 750 #define mod 1000000007 int len,p[maxn]; long long dp[maxn][maxn][3][3]; char s[maxn]; void match(){ stack<int>stk; while(!stk.empty())stk.pop(); for(int i=0;i<len;i++){ if(stk.empty()){ stk.push(i); continue; } int t=stk.top(); if(s[i]==')'&&s[t]=='('){ p[t]=i,p[i]=t; stk.pop(); } else stk.push(i); } } void dfs(int l,int r){ if(l==r)return; if(l+1==r){//只有一种情况 dp[l][r][0][1]=dp[l][r][1][0]=dp[l][r][0][2]=dp[l][r][2][0]=1; return; } if(p[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; } //剩下的情况就是不能配对的情况 int tmp=p[l]; dfs(l,tmp);dfs(tmp+1,r); for(int i=0;i<3;i++) for(int j=0;j<3;j++) for(int k=0;k<3;k++) for(int m=0;m<3;m++) if(!((k==1 && m==1) || (k==2 && m==2))) dp[l][r][i][j]=(dp[l][r][i][j]+(dp[l][tmp][i][k]*dp[tmp+1][r][m][j])%mod)%mod; } int main(){ cin>>s;len=strlen(s); memset(dp,0,sizeof dp); match();dfs(0,len-1); long long 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); }