AK大佬的代码,蒟蒻看了一个小时都没有搞懂
dp[][][1] 和 dp[][][0] 的区别
还有sm[][]的意思
#include<bits/stdc++.h>
#define cs const
#define pb push_back
using namespace std;
typedef vector<int> vi;
typedef long long ll;
cs int mod=1e9+7;
int add(int a,int b){
return a+b>=mod?a+b-mod:a+b;
}
int dec(int a,int b){
return a-b<0?a-b+mod:a-b;
}
int mul(int a,int b){
return 1ll*a*b%mod;
}
void Add(int &a,int b){
a=add(a,b);
}
void Dec(int &a,int b){
a=dec(a,b);
}
void Mul(int &a,int b){
a=mul(a,b);
}
cs int N=505;
int n,k;
char S[N];
int dp[N][N][2];
int sm[N][N];
bool ec[N][N][2];
int nxt[N];
int main()
{
cin>>n>>k;
scanf("%s",S+1);
for(int i=1;i<=n;i++){
nxt[i]=n+1;
for(int j=i;j<=n;j++){
if(S[j]=='('||S[j]==')'){
nxt[i]=j;//标记每一个字符后面的第一个括号出现的位置
break;
}
}
}
for(int len=2;len<=n;len++){//区间dp基本操作,枚举区间长度
for(int l=1;l<=n;l++){//枚举区间起点
int r=l+len-1;
if(r>n){
break;//判定
}
int c=0;
if((S[l]=='('||S[l]=='?')&&(S[r]==')'||S[r]=='?')){//考虑括号内的情况(&……%*……*)
if(r-l-1==0){//考虑()
Add(c,1);
}else{//考虑(***) 和 (())
Add(c,dp[l+1][r-1][1]);
if(r-l-1<=k){
if(nxt[l+1]>=r){
Add(c,1);
}
}
}
int z=min(k,r-l-2);//枚举长度
for(int t=1;t<=z;t++){//(**())
if(S[l+t]==')'||S[l+t]=='('){
break;
}
Add(c,dp[l+t+1][r-1][1]);
}
for(int t=1;t<=z;t++){//(()***)//内括号
if(S[r-t]==')'||S[r-t]=='('){
break;
}
Add(c,dp[l+1][r-t-1][1]);
}
}
dp[l][r][0]=c;//(())的情况 处理完括号内括号的情况 ???
for(int i=l+1;i<r;i++){// 接着做括号里有*又有括号的情况 ???
int p=min(r,nxt[i+1]);//枚举边界 ???
p=min(p,i+k+1);
Add(c,mul(dp[l][i][0],dec(sm[i+1][r],sm[p+1][r])));//后缀和+乘法原理 ???
}
dp[l][r][1]=c;
sm[l][r]=add(c,sm[l+1][r]);//后缀合
}
}
cout<<dp[1][n][1]<<'\n';///输出
return 0;
}