#include<stdio.h>

#include<string>

#include<map>

#include<vector>

#include<cmath>

#include<stdlib.h>

#include<string.h>

#include<algorithm>

#include<iostream>

using namespace std;

const int N=105;

const int MOD=1e9+7;

int n;

int a[N];

char ch[N];

void rd(int&x){

    char ch;

    for(ch=getchar();ch<'0' || ch>'9';ch=getchar());

    x=0;

    for(;ch>='0' && ch<='9';ch=getchar()) x=x*10+ch-'0';

}

long long res;

long long sum[N][N][N];  /*sum[i][j][k]表示区间i到j最后一个取第k个符号的答案和   ,sum[i][j][n+1]表示区间i到的答案总和*/

long long A[N];

long long calc(long long x,long long y,char c){

    if(c=='+') return (x+y)%MOD;

    else if(c=='-') return (x-y+MOD)%MOD;

    else return (x*y)%MOD;

}



long long C[N][N];

void solve(){

    memset(sol,0,sizeof sol);

    memset(sum,0,sizeof sum);

    for(int i=1;i<=n;i++){

        sum[i][i][n+1]=a[i];

    }

    for(int i=1;i<n;i++){

        sum[i][i+1][n+1]=sum[i][i+1][i]=calc(a[i],a[i+1],ch[i]);

    }

    for(int j=3;j<=n;j++)

        for(int i=1;i+j-1<=n;i++){

            int l=i,r=i+j-1;

            for(int k=l;k<r;k++){

                if(ch[k]=='+'){

                /*

                第k个符号左边   第l到k个数字。这个区间的方案个数 A[k-l]          sum[l][k][n+1] l到k的和

                第k个符号右边   第k+1到r个数字  这个区间的方案个数 A[r-k-1]    sum[k+1][r][n+1]  k+1到r的和

                设左边 A[k-l]个值   a1,a2, ........   ai指的都是左边这个区间由某一顺序得到的一个值,能够将它和一个操作序列等同

                设右边 A[r-k-1] 个值   b1,b2, ........   

                (a1+a2........) +  (b1,b2.............)         对于每一个a,被加A[r-k-1]次 ,对于每一个b。被加A[k-l]次

                减法同理

                乘法特殊一点

                (a1+a2........) *  (b1,b2.............)  乘法分配率,直接将两部分的总和相乘就可以

            */

            sum[l][r][k]=(sum[l][k][n+1]*A[r-k-1]+sum[k+1][r][n+1]*A[k-l])%MOD;

                }else if(ch[k]=='-'){

                    sum[l][r][k]=(sum[l][k][n+1]*A[r-k-1]-sum[k+1][r][n+1]*A[k-l])%MOD;

                    sum[l][r][k]=(sum[l][r][k]+MOD)%MOD;

                }else{

                    sum[l][r][k]=(sum[l][k][n+1]*sum[k+1][r][n+1])%MOD;

                }

                /*

                之前算的是(左边的选择序列)+(右边的选择序列)。可是左右两边也有先后。再乘个组合数,比赛时这个想了好久才想到

                对于上面的每一个ai和bj。他们在  遇到区间的最后一个操作符号后,须要再乘以一个组合数,由于之前的ai和bj是这种

                ai:(操作1,操作2,操作3.。。。。操作n)+  bj:(操作n+1,操作n+2,操作n+3.。

。。

。)。可是不一定是ai的操作序列全在前面的。至于为什是组合不是排列

                由于每一个ai和bj自己内部已经是有序了的。感觉这样讲的挺清楚了吧。自己比赛的时候这里卡了挺就久的。可是细致想一下。还是能够明确的

                */

                   sum[l][r][k]=(sum[l][r][k]*C[r-l-1][k-l])%MOD;

                   sum[l][r][n+1]=(sum[l][r][n+1]+sum[l][r][k])%MOD;

                   sum[l][r][n+1]=(sum[l][r][n+1]+MOD)%MOD;

            }

        }

        printf("%I64d\n",sum[1][n][n+1]);

}

int main(){

#ifndef ONLINE_JUDGE

    freopen("aaa","r",stdin);

#endif

    int T;

    int q;

    A[0]=1;/*A是全排列 C是组合 ,预处理这两个*/

    for(int i=1;i<N;i++) A[i]=(A[i-1]*i)%MOD;

    

    for(int i=0;i<N;i++) C[i][0]=1;

    for(int i=1;i<N;i++) for(int j=0;j<=i;j++) {

        if(j==0 || j==i) C[i][j]=1;

        else C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD;

    }

    while(~scanf("%d",&n)){

        for(int i=1;i<=n;i++) scanf("%d",&a[i]);

        scanf("%s",ch+1);

        solve();

    }

    return 0;

}

hdu5396 Expression 区间dp +排列组合的更多相关文章

  1. HDU 5151 Sit sit sit 区间DP + 排列组合

    Sit sit sit 问题描述 在一个XX大学中有NN张椅子排成一排,椅子上都没有人,每张椅子都有颜色,分别为蓝色或者红色. 接下来依次来了NN个学生,标号依次为1,2,3,...,N. 对于每个学 ...

  2. [hdu5396 Expression]区间DP

    题意:给一个表达式,求所有的计算顺序产生的结果总和 思路:比较明显的区间dp,令dp[l][r]为闭区间[l,r]的所有可能的结果和,考虑最后一个符号的位置k,k必须在l,r之间,则l≤k<r, ...

  3. 【BZOJ】2111: [ZJOI2010]Perm 排列计数 计数DP+排列组合+lucas

    [题目]BZOJ 2111 [题意]求有多少1~n的排列,满足\(A_i>A_{\frac{i}{2}}\),输出对p取模的结果.\(n \leq 10^6,p \leq 10^9\),p是素数 ...

  4. 【BZOJ】4559: [JLoi2016]成绩比较 计数DP+排列组合+拉格朗日插值

    [题意]n位同学(其中一位是B神),m门必修课,每门必修课的分数是[1,Ui].B神碾压了k位同学(所有课分数<=B神),且第x门课有rx-1位同学的分数高于B神,求满足条件的分数情况数.当有一 ...

  5. G.subsequence 1(dp + 排列组合)

    subsequence 1 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 You are ...

  6. hdu 5396 Expression(区间dp)

    Problem Description Teacher Mai has n numbers a1,a2,⋯,anand n−1 operators("+", "-&quo ...

  7. LightOJ1005 Rooks(DP/排列组合)

    题目是在n*n的棋盘上放k个车使其不互相攻击的方案数. 首先可以明确的是n*n最多只能合法地放n个车,即每一行都指派一个列去放车. dp[i][j]表示棋盘前i行总共放了j个车的方案数 dp[0][0 ...

  8. HDU 5816 状压DP&排列组合

    ---恢复内容开始--- Hearthstone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java ...

  9. bzoj 3398 [Usaco2009 Feb]Bullcow 牡牛和牝牛——前缀和优化dp / 排列组合

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3398 好简单呀.而且是自己想出来的. dp[ i ]表示最后一个牡牛在 i 的方案数. 当前 ...

随机推荐

  1. 联想 Vibe Shot(Z90-7) 免recovery 获取ROOT权限 救砖 VIBEUI V3.1_1625

    >>>重点介绍<<< 第一:本刷机包可卡刷可线刷,刷机包比较大的原因是采用同时兼容卡刷和线刷的格式,所以比较大第二:[卡刷方法]卡刷不要解压刷机包,直接传入手机后用 ...

  2. 还是关于编码——decode & encode的探究

    最近被py3.4中的编码折磨的不要不要的,decode & encode的使用.功能貌似在2.7—3.0有一个巨大的变化.网上查询的一些解答很多是基于2.7中的unicode功能,给出的解答是 ...

  3. 6.14 提取第n个分割的子串

    问题:从字符串中提取出一个指定的.由分割符隔开的子字符串.create view v as select 'mo,larry,curly' as namefrom t1union allselect ...

  4. 运用反射时报错java.lang.NoSuchMethodException,以解决,记录一下

    问题:想调用service类中的私有方法时, Method target=clz.getMethod("say", String.class);用Class的getMethod报错 ...

  5. Discuz伪静态代码

    <?php /** * [伪静态跳转(xugui_redirect.{modulename})] (C)2012-2099 Powered by 懒人V难人. * Version: 1.0 * ...

  6. Solr搜索引擎 — 通过mysql配置数据源

    一,准备数据库数据表结构 CREATE TABLE `app` ( `id` int(11) NOT NULL AUTO_INCREMENT, `app_name` varchar(255) NOT ...

  7. C++写注册表

    1.       注册表简介 注册表是为Windows NT和Windows95中所有32位硬件/驱动和32位应用程序设计的数据文件,用于存储系统和应用程序的设置信息.16位驱动在Winnt (Win ...

  8. vue-cli的项目加入骨架屏

    在原生APP中我们经常可以看到,打开app时候,内容还没出来,app会被别的内容替代,这样很好的提升了用户体验.那么在webApp中,我们如何避免白屏的尴尬情况呢?可以通过 vue-skeleton- ...

  9. POJ P2096 Collecting Bugs

    思路 分类讨论,不妨先设$DP[i][j]$表示已经发现$i$种子系统中有$n$种$bug$无非只有四种情况 发现的$bug$在旧的系统旧的分类,概率$p1$是$(i/s)*(j/n)$. 发现的$b ...

  10. 这几道Java集合框架面试题在面试中几乎必问

    Arraylist 与 LinkedList 异同 1. 是否保证线程安全: ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全: 2. 底层数据结构: Arraylis ...