首页 > 代码库 > BJOI2014 路径

BJOI2014 路径

3767. 【BJOI2014】路径 (Standard IO)

Time Limits: 1000 ms  Memory Limits: 262144 KB     

Description

在一个N个节点的无向图(没有自环、重边)上,每个点都有一个符号,可能是数字,也可能是加号、减号、乘号、除号、小括号。你要在这个图上数一数,有多少种走恰好K个节点的方法,使得路过的符号串起来能够得到一个算数表达式 算数表达式。路径的起点和终点可以任意选择。

所谓算数表达式 算数表达式,就是由运算符连接起来的一系列数字。括号可以插入在表达式中以表明运算顺序。

注意,你要处理各种情况,比如数字不能有多余的前导0,减号只有前面没有运算符或数字的时候才可以当成负号,括号可以任意添加(但不能有空括号),0可以做除数(我们只考虑文法而不考虑语意),加号不能当正号。

例如,下面的是合法的表达式:

-0/ 0

((0)+(((2*3+4)+(-5)+7))+(-(2*3)*6))

而下面的不是合法的表达式:

001+0

1+2(2)

3+-3

--1

+1

()
 

Input

第一行三个整数N,M,K,表示点的数量,边的数量和走的节点数。

第二行一个字符串,表示每个点的符号。

接下来M行,每行两个数,表示一条边连的两个点的编号。

Output

输出一行一个整数,表示走的方法数。这个数可能比较大,你只需要输出它模1000000007的余数即可。
 

Sample Input

6 10 3

)(1*+0

1 2

1 3

1 4

2 3

3 4

2 5

3 5

3 6

4 6

5 6

Sample Output

10
 

Data Constraint

对于40%的数据,N,M,K≤10

对于100%的数据,1≤N≤20,0≤M≤N×(N-1)/ 2,0≤K≤30
 

Hint

【样例解释】

一共有10条路径,构成的表达式依次是101, (1), 1+1, 1+0, 1*1, 1*0, 0+0, 0+1, 0*0, 0*1
 

 

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\n",xzq);}