题意:有n个数字,n-1个运算符,每个运算符的顺序可以任意,因此一共有 (n - 1)! 种运算顺序,得到 (n - 1)! 个运算结果,然后求这些运算结果之和 MOD 1e9+7.

分析:

类比最优矩阵链乘,枚举区间[l, r]中最后一个运算符的位置k。

如果运算符为乘法的话,那么根据乘法分配率这个乘法会分配进去。

这个区间中一共有r - l个运算符,其中最后一个运算符已经定了是第k个,左区间[l, k]有k - l个运算符,右区间[k + 1, r]有 r - k - 1 个运算符。

而且左、右区间运算符的先后顺序确定以后,两个区间之间的顺序是互不影响的,因此这样相同的结果一共有C(r - l - 1, k - l)

因此答案还要乘上这个数,d(i, j) += d(i, k) * d(k + 1, r) * C(r - l - 1, k - l) | op[k] = *

但如果是加减法的话就不能直接按照运算符进行区间合并了。

对于左区间的确定的一个运算顺序,右区间一共有 (r - k - 1)! 个运算结果,所以答案累加一个 d(l, k) * (r - k - 1)!

同样地,对于右区间一个确定的操作顺序,左区间对应有 (k - l)! 个运算结果,答案累加一个 d(k + 1, r) * (k - l)!

最后确定两个区间 r - l - 1 个运算符的顺序,最终答案乘上 C(r - l - 1, k - l)

最后总结一下答案就是:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; typedef long long LL; const int maxn = + ;
const LL MOD = ; int n;
LL a[maxn];
LL fac[maxn], C[maxn][maxn];
char op[maxn]; int vis[maxn][maxn];
LL d[maxn][maxn]; LL dp(int l, int r)
{
if(vis[l][r]) return d[l][r];
LL& ans = d[l][r];
ans = ;
vis[l][r] = true;
if(l == r) return ans = a[l];
if(l + == r)
{
if(op[l] == '*') return ans = a[l] * a[r] % MOD;
if(op[l] == '+') return ans = (a[l] + a[r]) % MOD;
if(op[l] == '-') return ans = (((a[l] - a[r]) % MOD) + MOD) % MOD;
}
for(int k = l; k < r; k++)
{
LL t1 = dp(l, k), t2 = dp(k + , r);
LL t;
if(op[k] == '*')
{
t = t1 * t2 % MOD;
t = t * C[r - l - ][k - l];
ans = (ans + t) % MOD;
continue;
} t1 = t1 * fac[r - k - ] % MOD;
t2 = t2 * fac[k - l] % MOD;
if(op[k] == '+') t = (t1 + t2) % MOD;
else t = (((t1 - t2) % MOD) + MOD) % MOD;
t = t * C[r - l - ][k - l];
ans = (ans + t) % MOD;
} return ans;
} int main()
{
fac[] = ;
for(int i = ; i < maxn; i++) fac[i] = fac[i - ] * i % MOD;
for(int i = ; i < maxn; i++) C[i][] = C[i][i] = 1LL;
for(int i = ; i < maxn; i++)
for(int j = ; j < i; j++) C[i][j] = (C[i-][j] + C[i-][j-]) % MOD; while(scanf("%d", &n) == && n)
{
for(int i = ; i <= n; i++) scanf("%I64d", a + i);
scanf("%s", op + );
memset(vis, false, sizeof(vis));
memset(vis, , sizeof(vis));
printf("%I64d\n", dp(, n));
} return ;
}

代码君

HDU 5396 区间DP 数学 Expression的更多相关文章

  1. hdu 4283 区间dp

    You Are the One Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  2. HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化

    HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...

  3. HDU 4293---Groups(区间DP)

    题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=4293 Problem Description After the regional con ...

  4. String painter HDU - 2476 -区间DP

    HDU - 2476 思路:分解问题,先考虑从一个空串染色成 B串的最小花费 ,区间DP可以解决这个问题 具体的就是,当 str [ l ] = = str [ r ]时 dp [ L ] [ R ] ...

  5. HDU 4632 区间DP 取模

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4632 注意到任意一个回文子序列收尾两个字符一定是相同的,于是可以区间dp,用dp[i][j]表示原字 ...

  6. 2016 ACM/ICPC Asia Regional Shenyang Online 1009/HDU 5900 区间dp

    QSC and Master Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  7. HDU 4570(区间dp)

    E - Multi-bit Trie Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...

  8. hdu 2476 区间dp

    题意: 给出两个串s1和s2,一次只能将一个区间刷一次,问最少几次能让s1=s2 例如zzzzzfzzzzz,长度为11,我们就将下标看做0~10 先将0~10刷一次,变成aaaaaaaaaaa 1~ ...

  9. hdu 4632(区间dp)

    Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/ ...

随机推荐

  1. yum指令之修复

    折腾着搞 openvpn 网站服务器 yum指令 出了点问题 ------------------------------------------------------------ [root@cl ...

  2. enable assembly bind failure logging (Fusion) in .NET

    今天遇到新建wcf项目编译成64位版本在64位windows上无法运气的,问题 先百度了一下如何查看程序集加载日志: Add the following values to HKEY_LOCAL_MA ...

  3. java校验maven下载的jar文件

    有时候maven真的很坑! 有时候提示invalid LOC header (bad signat signature), 但又有时候什么都不提示,工程报错,情况有肯多中,不知道大家遇到过几种诡异的. ...

  4. java面试题(杨晓峰)---第八讲谈谈Vector,ArrayList,LinkedList有何区别?

    Vector,ArrayList,LinkedList均为线性的数据结构,但是从现实方式与应用场景中又存在差别. 1 底层实现方式 ArrayList内部数组来实现,LinkedList内部采用双向链 ...

  5. [web开发] Vue + spring boot + echart 微博爬虫展示平台

    1.微博登录 2.爬取数据 3.mysql存储 4.pyechart本地展示 5.用vue搭建网站web展示 先放图: 1.微博登录 新浪微博的登录不是简单的post就能解决的,他的登录有加密,所以我 ...

  6. ReferenceError: internalBinding is not defined

    ReferenceError: internalBinding is not defined at internal/util/inspect.js:31:15 at req_ (D:\workspa ...

  7. js 获取当前年月日时分秒星期

    $("#aa").click(function () { var date = new Date(); this.year = date.getFullYear(); this.m ...

  8. iBatis for net 框架使用

    简介:ibatis 一词来源于“internet”和“abatis”的组合,是一个由Clinton Begin在2001年发起的开放源代码项目,到后面发展的版本叫MyBatis但都是指的同一个东西.最 ...

  9. 安装JDK1.8以及配置环境变量的步骤

    一. 首先到官网下载jdk1.8,下载的版本分为windows和linux,这里需要安装操作系统进行下载.我的是64位就下载x64,32位系统则下载x86 二. 然后就是安装,双击进行安装,这里不用更 ...

  10. thinkphp的使用——隐藏index.php

    官方默认的.htaccess文件 <IfModule mod_rewrite.c>  Options +FollowSymlinks -Multiviews  RewriteEngine ...