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\n",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("\n");
       }*/
   printf("%lld\n",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\n",&(op[1]));
        solve();
    }
    return 0;
}

 

posted on 2015-08-21 14:31  爱装逼的书呆子  阅读(163)  评论(0编辑  收藏  举报

导航