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);
}
原文地址:https://www.cnblogs.com/applejxt/p/3911614.html