• BJOI2014 路径


    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
    ",xzq);
    }
  • 相关阅读:
    【Luogu1095】守望者的逃离
    python基础学习1-类相关内置函数
    python基础学习1-面向对象
    python基础学习1 -异常捕获
    python基础学习1-类,对象
    python基础学习1-正则表达式
    python基础学习1-反射
    python基础学习1-日志信息
    python基础学习1-生成器,递归函数
    python基础学习1-json,pickle的序列化和反序列化
  • 原文地址:https://www.cnblogs.com/applejxt/p/3911614.html
Copyright © 2020-2023  润新知