zoukankan      html  css  js  c++  java
  • hdu5396 Expression

    Problem Description
    Teacher Mai has n numbers a1,a2,,anand n1 operators("+", "-" or "*")op1,op2,,opn1, which are arranged in the form a1 op1 a2 op2 a3  an.

    He wants to erase numbers one by one. In i-th round, there are n+1i numbers remained. He can erase two adjacent numbers and the operator between them, and then put a new number (derived from this one operation) in this position. After n1 rounds, there is the only one number remained. The result of this sequence of operations is the last number remained.


    He wants to know the sum of results of all different sequences of operations. Two sequences of operations are considered different if and only if in one round he chooses different numbers.

    For example, a possible sequence of operations for "1+4683" is 1+46831+4(2)31+(8)3(7)321.
     

    Input
    There are multiple test cases.

    For each test case, the first line contains one number n(2n100).

    The second line contains n integers a1,a2,,an(0ai109).

    The third line contains a string with length n1 consisting "+","-" and "*", which represents the operator sequence.
     

    Output
    For each test case print the answer modulo 109+7.
     

    Sample Input
    3 3 2 1 -+ 5 1 4 6 8 3 +*-*
     

    Sample Output
    2

    999999689

    这题是一道很好的区间dp,看完解题报告后才会做,先用状态dp[i][j]表示区间[i,j]里的和,用A[i]表示1到i的阶乘,c[i][j]表示组合数。那么我们在区间[i,j]里枚举k,(i<=k<j),如果当前第k个是乘号,那么根据乘法分配律,t=(dp[i][k]*dp[k+1][j])%MOD;,如果当前第k个是加或减,那么t=dp[i][k]*t=(dp[i][k]*A[j-k-1]+dp[k+1][j]*A[k-i])%MOD;因为选择的这个加号或减号两端的运算是互不干扰的,而一边的运算次数为另一边的组合数,所以有这样的状态方程,另外还要乘上一个c[j-i-1][k-i],因为我们确定的是两边各自的运算,但是我们可以这样的顺序取:左边先算乘法,然后右边算加法,再左边算减法...相当于安排左边符号运算在总运算个数的次序。还有注意(a+MOD)%MOD要在最后才能用,前面不能用,只能用a%MOD,不然会使结果改变。

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<string>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define MOD 1000000007
    char s[106];
    ll a[106],dp[106][106],A[106],c[106][106];
    void init()
    {
        int i,j;
        A[0]=1;
        A[1]=1;
        A[2]=2;
        for(i=3;i<=100;i++){
            A[i]=(A[i-1]*(ll)i)%MOD;
        }
        for(i=1;i<=100;i++)c[i][0]=1;
    
        for(i=1;i<=100;i++){
            for(j=1;j<=i;j++){
                if(i==j)c[i][j]=1;
                else if(i>j)
                c[i][j]=(c[i-1][j]+c[i-1][j-1])%MOD;
            }
        }
    }
    
    int main()
    {
        int n,m,i,j,T,len,k;
        ll t;
        init();
        while(scanf("%d",&n)!=EOF)
        {
            for(i=1;i<=n;i++){
                scanf("%lld",&a[i]);
                dp[i][i]=a[i];
            }
            scanf("%s",s+1);
            for(i=1;i<=n-1;i++){
                if(s[i]=='+'){
                    dp[i][i+1]=(a[i]+a[i+1])%MOD;
                }
                else if(s[i]=='-'){
                    dp[i][i+1]=(a[i]-a[i+1])%MOD;
                }
                else if(s[i]=='*')
                    dp[i][i+1]=(a[i]*a[i+1])%MOD;   /*!!!!!!!!!!!!!!!!!*/
            }
            for(len=3;len<=n;len++){
                for(i=1;i+len-1<=n;i++){
                    j=i+len-1;
                    dp[i][j]=0;
                    for(k=i;k<j;k++){
                        t=0;
                        if(s[k]=='*'){
                            t=(dp[i][k]*dp[k+1][j])%MOD;
                        }
                        else if(s[k]=='+'){
                            t=(dp[i][k]*A[j-k-1]+dp[k+1][j]*A[k-i])%MOD;
    
                        }
                        else if(s[k]=='-'){
                            t=(dp[i][k]*A[j-k-1]-dp[k+1][j]*A[k-i])%MOD;
                        }
                        dp[i][j]=(dp[i][j]+t*c[j-i-1][k-i])%MOD;
                    }
    
                }
            }
            printf("%lld
    ",(dp[1][n]+MOD)%MOD);
        }
        return 0;
    }
    


  • 相关阅读:
    设计模式之装饰模式(Decorator)
    原型模式(浅克隆和深克隆)
    (原创)C#初级教程学习笔记001-学习路线
    (原创)C#零基础学习笔记012-多线程开发
    (原创)C#零基础学习笔记011-事件和委托
    (原创)C#零基础学习笔记010-数据流技术
    (原创)C#零基础学习笔记009-异常处理
    (原创)C#零基础学习笔记008-C#集合处理
    (原创)C#零基础学习笔记007-面向对象的特性
    (原创)C#零基础学习笔记006-面向对象编程基础
  • 原文地址:https://www.cnblogs.com/herumw/p/9464668.html
Copyright © 2011-2022 走看看