码迷,mamicode.com
首页 > 其他好文 > 详细

BJOI2014 路径

时间:2014-08-14 08:13:08      阅读:368      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   color   io   数据   for   ar   

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);
}

 

BJOI2014 路径,布布扣,bubuko.com

BJOI2014 路径

标签:des   style   blog   color   io   数据   for   ar   

原文地址:http://www.cnblogs.com/applejxt/p/3911614.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!