标签:code scanf bsp 序列 子序列 ack ring \n def
用所有合法序列的方案数减不包含题目中要求的子序列的合法序列数
后者用AC自动机维护一下dp就好
1 #include<queue> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define mod 1000000007 6 using namespace std; 7 int n,m,cnt,tot,minu,ans; 8 char son[205]; 9 int al[205][105]; 10 int dp[205][205][105]; 11 int ed[205]; 12 int tr[205][2]; 13 int fail[205]; 14 void build(char b[]){ 15 int now=0; 16 int len=strlen(b+1); 17 for(int i=1;i<=len;i++){ 18 int k=-1; 19 if(b[i]==‘(‘)k=1; 20 else k=0; 21 if(!tr[now][k])tr[now][k]=++cnt; 22 now=tr[now][k]; 23 } 24 ed[now]=1; 25 } 26 void getfail(){ 27 queue<int>que; 28 int now=0; 29 if(tr[0][0])que.push(tr[0][0]); 30 if(tr[0][1])que.push(tr[0][1]); 31 while(!que.empty()){ 32 int s=que.front(); 33 que.pop(); 34 if(tr[s][0]){ 35 fail[tr[s][0]]=tr[fail[s]][0]; 36 que.push(tr[s][0]); 37 }else{ 38 tr[s][0]=tr[fail[s]][0]; 39 } 40 if(tr[s][1]){ 41 fail[tr[s][1]]=tr[fail[s]][1]; 42 que.push(tr[s][1]); 43 }else{ 44 tr[s][1]=tr[fail[s]][1]; 45 } 46 } 47 } 48 int main(){ 49 scanf("%d",&n); 50 scanf("%s",son+1); 51 build(son); 52 getfail(); 53 al[1][1]=1; 54 for(int i=2;i<=2*n;i++){ 55 for(int j=0;j<=n;j++){ 56 (al[i][j]+=al[i-1][j+1])%=mod; 57 if(j)(al[i][j]+=al[i-1][j-1])%=mod; 58 } 59 } 60 tot=al[2*n][0]; 61 dp[0][0][0]=1; 62 for(int i=1;i<=2*n;i++){ 63 for(int j=0;j<=cnt;j++){ 64 for(int k=0;k<=n;k++){ 65 if(!ed[tr[j][0]]){ 66 (dp[i][tr[j][0]][k]+=dp[i-1][j][k+1])%=mod; 67 } 68 if(!ed[tr[j][1]]&&k){ 69 (dp[i][tr[j][1]][k]+=dp[i-1][j][k-1])%=mod; 70 } 71 } 72 } 73 } 74 for(int i=0;i<cnt;i++){ 75 (minu+=dp[2*n][i][0])%=mod; 76 } 77 ans=((tot-minu)%mod+mod)%mod; 78 printf("%d\n",ans); 79 return 0; 80 }
CF1015F Bracket Substring(dp+Trie图)
标签:code scanf bsp 序列 子序列 ack ring \n def
原文地址:https://www.cnblogs.com/lnxcj/p/9898004.html