3767. 【BJOI2014】路径 (Standard IO)
Time Limits: 1000 ms Memory Limits: 262144 KB
Dp方程;f[i][j][k][l]表示已走i个点,现在在第j个点,左括号比右括号多k个,l为是否有前导0。 的方案数。转移方程分类讨论即可,比较简单。
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<cstring> using namespace std; int mo=1000000007; char s[45]; int f[32][22][32][32][2]; int xzq,i,j,k,l,ii,n,m,t,x,z; bool p[22][22]; bool pd(int x,int z) { if(s[x-1]>='0'&&s[x-1]<='9'){ if(s[z-1]>='0'&&s[z-1]<='9')return true; else if(s[z-1]=='+'||s[z-1]=='-'||s[z-1]=='*'||s[z-1]=='/')return true; else if(s[z-1]==')')return true; else return false; } if(s[x-1]=='+'||s[x-1]=='-'||s[x-1]=='*'||s[x-1]=='/'){ if(s[z-1]>='0'&&s[z-1]<='9')return true; else if(s[z-1]=='(')return true; else return false; } if(s[x-1]=='('){ if(s[z-1]>='0'&&s[z-1]<='9')return true; else if(s[z-1]=='(')return true; else if(s[z-1]=='-')return true; else return false; } if(s[x-1]==')'){ if(s[z-1]==')')return true; else if(s[z-1]=='+'||s[z-1]=='-'||s[z-1]=='*'||s[z-1]=='/')return true; else return false; } } int main() { scanf("%d%d%d",&n,&m,&t); scanf("%s",&s); memset(p,false,sizeof(p)); for(i=1;i<=m;i++){ scanf("%d%d",&x,&z); p[x][z]=pd(x,z); p[z][x]=pd(z,x); } memset(f,255,sizeof(f)); for(i=1;i<=n;i++){ if(s[i-1]=='(')f[1][i][1][0][0]=1; if(s[i-1]=='0')f[1][i][0][0][1]=1; if(s[i-1]>='1'&&s[i-1]<='9')f[1][i][0][0][0]=1; if(s[i-1]=='-')f[1][i][0][0][0]=1; } for(i=2;i<=t;i++){ for(j=1;j<=n;j++){ for(k=0;k<=i;k++){ for(l=0;l<=min(k,i-k);l++){ for(ii=1;ii<=n;ii++)if(p[ii][j]){ if(s[ii-1]=='0'){ if(s[j-1]>='0'&&s[j-1]<='9'){ if(f[i-1][ii][k][l][0]!=-1){ if(f[i][j][k][l][0]==-1)f[i][j][k][l][0]=f[i-1][ii][k][l][0]; else f[i][j][k][l][0]=(f[i][j][k][l][0]+f[i-1][ii][k][l][0])%mo; } } else if(s[j-1]==')'){ if(l>=1){ if(f[i-1][ii][k][l-1][0]!=-1){ if(f[i][j][k][l][0]==-1)f[i][j][k][l][0]=f[i-1][ii][k][l-1][0]; else f[i][j][k][l][0]=(f[i][j][k][l][0]+f[i-1][ii][k][l-1][0])%mo; } if(f[i-1][ii][k][l-1][1]!=-1){ if(f[i][j][k][l][0]==-1)f[i][j][k][l][0]=f[i-1][ii][k][l-1][1]; else f[i][j][k][l][0]=(f[i][j][k][l][0]+f[i-1][ii][k][l-1][1])%mo; } } } else{ if(f[i-1][ii][k][l][0]!=-1){ if(f[i][j][k][l][0]==-1)f[i][j][k][l][0]=f[i-1][ii][k][l][0]; else f[i][j][k][l][0]=(f[i][j][k][l][0]+f[i-1][ii][k][l][0])%mo; } if(f[i-1][ii][k][l][1]!=-1){ if(f[i][j][k][l][0]==-1)f[i][j][k][l][0]=f[i-1][ii][k][l][1]; else f[i][j][k][l][0]=(f[i][j][k][l][0]+f[i-1][ii][k][l][1])%mo; } } } else{ if(s[j-1]=='0'){ if(s[ii-1]>='0'&&s[ii-1]<='9'){ if(f[i-1][ii][k][l][0]!=-1){ if(f[i][j][k][l][0]==-1)f[i][j][k][l][0]=f[i-1][ii][k][l][0]; else f[i][j][k][l][0]=(f[i][j][k][l][0]+f[i-1][ii][k][l][0])%mo; } } else{ if(f[i-1][ii][k][l][0]!=-1){ if(f[i][j][k][l][1]==-1)f[i][j][k][l][1]=f[i-1][ii][k][l][0]; else f[i][j][k][l][1]=(f[i][j][k][l][1]+f[i-1][ii][k][l][0])%mo; } } } else if(s[j-1]=='('){ if(k>=1){ if(f[i-1][ii][k-1][l][0]!=-1){ if(f[i][j][k][l][0]==-1)f[i][j][k][l][0]=f[i-1][ii][k-1][l][0]; else f[i][j][k][l][0]=(f[i][j][k][l][0]+f[i-1][ii][k-1][l][0])%mo; } } } else if(s[j-1]==')'){ if(l>=1){ if(f[i-1][ii][k][l-1][0]!=-1){ if(f[i][j][k][l][0]==-1)f[i][j][k][l][0]=f[i-1][ii][k][l-1][0]; else f[i][j][k][l][0]=(f[i][j][k][l][0]+f[i-1][ii][k][l-1][0])%mo; } } } else{ if(f[i-1][ii][k][l][0]!=-1){ if(f[i][j][k][l][0]==-1)f[i][j][k][l][0]=f[i-1][ii][k][l][0]; else f[i][j][k][l][0]=(f[i][j][k][l][0]+f[i-1][ii][k][l][0])%mo; } } } } } } } } xzq=0; for(i=1;i<=n;i++)if(s[i-1]!='+'&&s[i-1]!='-'&&s[i-1]!='*'&&s[i-1]!='/'){ for(j=0;j<=t;j++){ if(f[t][i][j][j][0]!=-1)xzq=(xzq+f[t][i][j][j][0])%mo; if(f[t][i][j][j][1]!=-1)xzq=(xzq+f[t][i][j][j][1])%mo; } } printf("%d ",xzq); }