zoukankan      html  css  js  c++  java
  • 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);
    }
  • 相关阅读:
    将Nginx添加到windows服务中
    springboot使用redis管理session
    GIT常用命令
    阻止360、谷歌浏览器表单自动填充
    谈谈对Spring IOC的理解
    同一个Nginx服务器同一端口配置多个代理服务
    LeetCode 653. Two Sum IV
    109. Convert Sorted List to Binary Search Tree(根据有序链表构造平衡的二叉查找树)
    108. Convert Sorted Array to Binary Search Tree(从有序数组中构造平衡的BST)
    LeetCode 236. Lowest Common Ancestor of a Binary Tree(二叉树求两点LCA)
  • 原文地址:https://www.cnblogs.com/applejxt/p/3911614.html
Copyright © 2011-2022 走看看