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 }
posted @ 2021-10-31 15:41  上官书房  阅读(113)  评论(1)    收藏  举报