zoukankan      html  css  js  c++  java
  • hdu5396(区间DP)

    题目意思:

    给定一个表达式,运算符没有优先级,求不同顺序计算,所有可能的得到的结果之和。

    由于运算符没有优先级,所以有多种顺序去计算,设d[i][j]表示[i,j]区间表达式通过不同顺序计算,所以可能得到的结果之和,

    枚举最后一次运算符是第t个,有可能是加减乘三种,所以需要不同处理。

    最后由于s[i][t],s[t+1][j],内部运算的绝对顺序确定,但是s[i][j]整体的相对顺序还没确定,所以乘上C[t-i][j-i-1].

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #define maxn  150
    #define LL long long
    #define MOD 1000000007
    using namespace std;
    LL s[maxn][maxn];
    LL C[maxn][maxn];
    LL    fac[maxn];
    int   n;
    int   a[maxn];
    char  op[maxn];
    void init()
    {
       fac[0]=1;
       for(int i=1;i<maxn;i++)
       {
         fac[i]=(fac[i-1]*i)%MOD;
       }
       C[0][0]=1;
       for(int j=1;j<maxn;j++)
       {
           C[0][j]=1;
           for(int i=1;i<maxn;i++)
        {
             C[i][j]=( (C[i][j-1]+C[i-1][j-1])) %MOD;  //²»Ñ¡£¬C[i][j-1],Ñ¡£¬C[i-1][j-1]
        }
       }
            // printf("%lld
    ",C[3][6]);
    }
    void init1()
    {
        memset(s,0,sizeof(s));
    }
    void solve()
    {
        for(int tt=1;tt<=n;tt++)
            for(int i=1;i<=n;i++)
        {
            int j=i+tt;
            if(j>n)
                continue;
            for(int t=i;t<=j-1;t++)
            {
                if(op[t]=='+')
                {
                    int k1=fac[t-i];
                    int k2=fac[j-(t+1)];
                    LL temp=0;
                    temp  = ( (k2*s[i][t])%MOD+(k1*s[t+1][j])%MOD )%MOD;
                    temp  = (temp *C[t-i][j-i-1]) %MOD;
                    s[i][j]= (s[i][j]+temp)%MOD;
                }
                else if(op[t]=='-')
                {
                    int k1=fac[t-i];
                    int k2=fac[j-(t+1)];
                    LL temp=0;
                    temp = ( (k2*s[i][t])%MOD-(k1*s[t+1][j])%MOD +MOD)%MOD;
                    temp  = (temp *C[t-i][j-i-1]) %MOD;
                     s[i][j]= (s[i][j]+temp)%MOD;
                }
                else if(op[t]=='*')
                {
                    LL temp=0;
                    temp =(s[i][t]*s[t+1][j]) % MOD;
                    temp = (temp *C[t-i][j-i-1]) %MOD;
                     s[i][j]= (s[i][j]+temp)%MOD;
                }
            }
        }
        /* for(int tt=1;tt<=n;tt++)
           {
               for(int i=1;i<=n;i++)
                {
                    int j=i+tt;
                     if(j>n)
                     continue;
                    printf("%lld ",(s[i][j]+MOD)%MOD );
                }
               printf("
    ");
           }*/
       printf("%lld
    ",s[1][n]);
    }
    int main()
    {
      // freopen("test.txt","r",stdin);
        init();
        while(~scanf("%d",&n))
        {
            init1();
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                s[i][i]=a[i];
                //printf("%d ",a[i]);
            }
            scanf("%s",&(op[1]));
          //  printf("%s
    ",&(op[1]));
            solve();
        }
        return 0;
    }
  • 相关阅读:
    人物装备的选取
    状压 + 背包
    村庄之间建立邮局
    woj
    括号匹配算面积(模拟)
    流程控制之if
    周末练习题(第一周)
    day04作业
    流程控制之for
    Python流程控制之while
  • 原文地址:https://www.cnblogs.com/xianbin7/p/4747818.html
Copyright © 2011-2022 走看看