ZOJ 3892 Available Computation Sequence(ZOJ Monthly, September 2015)

来源:互联网 发布:翻译软件app 编辑:程序博客网 时间:2024/05/22 09:06

【题目链接】http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3892

【解题报告】
比赛的时候并没有解决这道题目,因为理解错了题意,误认为每一种不同的方案应当保证计算所得结果不同,所以无法设计正确的dp转移方程。实际上在这道题目里只要加括号的方式不同即可认为是不同的方案,那么这道题目就可以区间dp解决。
dp[i][j][0]表示i~j个数字(向量)之间得到数字的方案数,
dp[i][j][1]表示i~j个数字(向量)之间得到向量的方案数,
那么我们枚举i~j之间最后一次操作的运算符,即在这个运算符两侧分别加上括号,根据dp状态转移即可。这道题写的很难受,细节处理的不好,所以参考了别人的代码:http://blog.csdn.net/stool_monster/article/details/48481843

【参考代码】

#include<bits/stdc++.h>using namespace std;const int mod=1e9+7;char S[100000+10];int len;char op[110];long long dp[110][110][2];int a[100000+10];int main(){    //freopen("zoj3892.txt","r",stdin);    int T;    cin>>T;    while(T--)    {        memset(dp,0,sizeof(dp));        memset(a,0,sizeof(a));        int n1=0,n2=0;        cin>>S;        len=strlen(S);        int cur=0;        while( cur<len )  //1~n1        {            if( S[cur]>='a' && S[cur]<='z' )            {                a[++n1]=1;                while( S[cur]>='a' && S[cur]<='z' )cur++;            }            else if( S[cur]>='1' && S[cur]<='9' )            {                a[++n1]=0;                while( S[cur]>='1' && S[cur]<='9' )cur++;            }            else            {                op[++n2]=S[cur++];            }        }        for( int i=1; i<=n1; i++ ) dp[i][i][a[i]]=1;        for( int i=n1; i>=1; i-- )            for( int j=i+1; j<=n1; j++ )            {                for( int k=i; k<j; k++ )                {                    if( op[k]=='*' )                    {                        dp[i][j][0]=( dp[i][j][0]+ dp[i][k][0]*dp[k+1][j][0]%mod ) %mod;                        dp[i][j][1]=( dp[i][j][1]+ dp[i][k][0]*dp[k+1][j][1]%mod ) %mod;                        dp[i][j][1]=( dp[i][j][1]+ dp[i][k][1]*dp[k+1][j][0]%mod ) %mod;                    }                    else if( op[k]=='.' )                    {                        dp[i][j][0]=( dp[i][j][0]+ dp[i][k][1]*dp[k+1][j][1]%mod ) %mod;                    }                    else if( op[k]=='^' )                    {                        dp[i][j][1]=( dp[i][j][1]+ dp[i][k][1]*dp[k+1][j][1]%mod ) %mod;                    }                    else if(  op[k]=='!' )                    {                        dp[i][j][0]=( dp[i][j][0]+ dp[i][k][1]*dp[k+1][j][1]%mod ) %mod;                        dp[i][j][1]=( dp[i][j][1]+ dp[i][k][0]*dp[k+1][j][0]%mod ) %mod;                        dp[i][j][1]=( dp[i][j][1]+ dp[i][k][0]*dp[k+1][j][1]%mod ) %mod;                        dp[i][j][1]=( dp[i][j][1]+ dp[i][k][1]*dp[k+1][j][0]%mod ) %mod;                    }                }            }        cout<<(dp[1][n1][0]+dp[1][n1][1])%mod<<endl;    }    return 0;}
0 0
原创粉丝点击