Luogu P7914 [CSP-S 2021] 括号序列(区间dp)
题目链接:https://www.luogu.com.cn/problem/P7914
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 inline ll re_ad() { 5 char ch=getchar(); ll x=0,f=1; 6 while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); } 7 while('0'<=ch && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); 8 return x*f; 9 } 10 11 const ll N=511,mod=1e9+7; 12 ll n,k,f[N][N],g[N][N][2]; 13 char s[N]; 14 bool X[N][N],vis[N][N]; 15 16 void dfs(ll x,ll y) { 17 if(vis[x][y]) return ; vis[x][y]=true; 18 for(ll i=y-1;i>x && y-i<=k;--i) if(X[i+1][y]) { dfs(x,i); (g[x][y][1]+=f[x][i]+g[x][i][0])%=mod; } 19 if(s[x]!='(' && s[x]!='?') { f[x][y]=g[x][y][0]=0; return ; } 20 if(s[y]!=')' && s[y]!='?') { f[x][y]=g[x][y][0]=0; return ; } 21 if(y==x+1) { f[x][y]=1,g[x][y][0]=0; return ; } 22 dfs(x+1,y-1); (f[x][y]+=f[x+1][y-1]+g[x+1][y-1][0]+(X[x+1][y-1] && y-x-1<=k))%mod; 23 for(ll i=1;i<=k && x+i+1<y-1;++i) if(X[x+1][x+i]) { dfs(x+i+1,y-1); (f[x][y]+=f[x+i+1][y-1]+g[x+i+1][y-1][0])%=mod; } 24 for(ll i=1;i<=k && x+1<y-i-1;++i) if(X[y-i][y-1]) { dfs(x+1,y-i-1); (f[x][y]+=f[x+1][y-i-1]+g[x+1][y-i-1][0])%=mod; } 25 for(ll i=x;i<y-1;++i) { dfs(x,i),dfs(i+1,y); (g[x][y][0]+=(f[x][i]+g[x][i][0]+g[x][i][1])*f[i+1][y]%mod)%=mod; } 26 } 27 28 int main() 29 { 30 n=re_ad(),k=re_ad(); scanf("%s",s+1); 31 for(ll i=1;i<=n;++i) for(ll j=i;j<=n && (s[j]=='*' || s[j]=='?');++j) X[i][j]=true; 32 dfs(1,n); printf("%lld\n",(f[1][n]+g[1][n][0])%mod); //printf("%d\n",vis[1][5]); 33 // for(ll i=1;i<=n;++i) for(ll j=i;j<=n;++j) printf("%lld %lld: %d %lld %lld %lld\n",i,j,X[i][j],f[i][j],g[i][j][0],g[i][j][1]); 34 return 0; 35 }