请求巨佬讲解一下代码,蒟蒻不懂
查看原帖
请求巨佬讲解一下代码,蒟蒻不懂
239251
Robert123456楼主2021/10/25 20:10

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;
}
2021/10/25 20:10
加载中...