习题链接
dp[i][j]表示序列前i个括号中左括号比右括号多j个方案数。需要记住的是我们只会往括号序列中插入左括号,因为我们判断一个序列不合法当且仅当此时左括号数目小于右括号数目。
需要注意的一点是当j等于0时需要特殊处理一下,因为j-1=-1,所以dp[i][0]=dp[i-1][1]+dp[i-1][0]
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=5005;
int f[N][N];
const int mod=1e9+7;
string s;
int n;
LL get() {
memset(f,0,sizeof(f));
f[0][0]=1;
for(int i=1;i<=n;i++) {
if(s[i-1]=='(' ) {
for(int j=1;j<=n;j++) {
f[i][j]=f[i-1][j-1];
}
} else {
f[i][0]=(f[i-1][1]+f[i-1][0])%mod;
for(int j=1;j<=n;j++) {
f[i][j]=(f[i-1][j+1]+f[i][j-1])%mod;
}
}
}
for(int i=0;i<=n;i++) {
if(f[n][i]) {
return f[n][i];
}
}
return -1;
}
int main() {
cin>>s;
n=s.size();
LL x=get(); //记录左括号的插入方案数
reverse(s.begin(),s.end()); //将原序列逆置
for(int i=0;i<n;i++) {
if(s[i]==')') {
s[i]='(';
} else {
s[i]=')';
}
}
LL y=get(); //记录右括号的插入方案数
cout<<(x*y)%mod;
return 0;
}