题意:给一个表达式,求所有的计算顺序产生的结果总和

思路:比较明显的区间dp,令dp[l][r]为闭区间[l,r]的所有可能的结果和,考虑最后一个符号的位置k,k必须在l,r之间,则l≤k<r,dp[l][r]=Σ{dp[l][k]?dp[k+1][r]}*(r-l-1)!/[(k-l)!(r-k-1)!],其中(r-l-1)!/[(k-l)!(r-k-1)!]表示从左区间和右区间选择符号的不同方法总数(把左右区间看成整体,那么符号的选择在整体间也有顺序,内部的顺序不用管,那是子问题需要考虑的),相当于(k-l)个0和(r-k-1)个1放一起的不同排列方法总数。

对花括号里面的'?'分为三种情况:

  1. '+'  假设左区间有x种可能的方法,右区间有y种可能的方法,由于分配律的存在,左边的所有结果和会重复计算y次,右边的所有结果和会重复计算x次,而左边共(k-l)个符号,右边共(r-k-1)个符号,所以合并后的答案dp[l][r]=dp[l][k]*(r-k-1)!+dp[k+1][r]*(k-l)!
  2. '-'   与'+'类似
  3. '*'   由分配律,合并后的答案dp[l][r]=dp[l][k]*dp[k+1][r]

  1. #pragma comment(linker, "/STACK:10240000")
  2. #include <map>
  3. #include <set>
  4. #include <cmath>
  5. #include <ctime>
  6. #include <deque>
  7. #include <queue>
  8. #include <stack>
  9. #include <vector>
  10. #include <cstdio>
  11. #include <string>
  12. #include <cstdlib>
  13. #include <cstring>
  14. #include <iostream>
  15. #include <algorithm>
  16.  
  17. using namespace std;
  18.  
  19. #define X first
  20. #define Y second
  21. #define pb push_back
  22. #define mp make_pair
  23. #define all(a) (a).begin(), (a).end()
  24. #define fillchar(a, x) memset(a, x, sizeof(a))
  25. #define copy(a, b) memcpy(a, b, sizeof(a))
  26.  
  27. typedef long long ll;
  28. typedef pair<int, int> pii;
  29. typedef unsigned long long ull;
  30.  
  31. //#ifndef ONLINE_JUDGE
  32. void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
  33. void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
  34. void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
  35. while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
  36. void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
  37. void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
  38. void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
  39. //#endif
  40. template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
  41. template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
  42.  
  43. const double PI = acos(-1.0);
  44. const int INF = 1e9 + ;
  45. const double EPS = 1e-12;
  46.  
  47. /* -------------------------------------------------------------------------------- */
  48.  
  49. template<int mod>
  50. struct ModInt {
  51. const static int MD = mod;
  52. int x;
  53. ModInt(ll x = ): x(x % MD) {}
  54. int get() { return x; }
  55.  
  56. ModInt operator + (const ModInt &that) const { int x0 = x + that.x; return ModInt(x0 < MD? x0 : x0 - MD); }
  57. ModInt operator - (const ModInt &that) const { int x0 = x - that.x; return ModInt(x0 < MD? x0 + MD : x0); }
  58. ModInt operator * (const ModInt &that) const { return ModInt((long long)x * that.x % MD); }
  59. ModInt operator / (const ModInt &that) const { return *this * that.inverse(); }
  60.  
  61. ModInt operator += (const ModInt &that) { x += that.x; if (x >= MD) x -= MD; }
  62. ModInt operator -= (const ModInt &that) { x -= that.x; if (x < ) x += MD; }
  63. ModInt operator *= (const ModInt &that) { x = (long long)x * that.x % MD; }
  64. ModInt operator /= (const ModInt &that) { *this = *this / that; }
  65.  
  66. ModInt inverse() const {
  67. int a = x, b = MD, u = , v = ;
  68. while(b) {
  69. int t = a / b;
  70. a -= t * b; std::swap(a, b);
  71. u -= t * v; std::swap(u, v);
  72. }
  73. if(u < ) u += MD;
  74. return u;
  75. }
  76.  
  77. };
  78. typedef ModInt<> mint;
  79.  
  80. const int maxn = 1e2 + ;
  81. const int md = 1e9 + ;
  82. mint dp[maxn][maxn], fac[maxn], facinv[maxn];
  83. int a[maxn];
  84. char s[maxn];
  85.  
  86. mint get(mint a, char ch, mint b, mint ca, mint cb) {
  87. if (ch == '+') return a * cb + b * ca;
  88. if (ch == '-') return a * cb - b * ca;
  89. if (ch == '*') return a * b;
  90. }
  91.  
  92. void init() {
  93. fac[] = facinv[] = ;
  94. for (int i = ; i < maxn; i ++) fac[i] = fac[i - ] * i;
  95. for (int i = ; i < maxn; i ++) facinv[i] = facinv[i - ] / i;
  96. }
  97.  
  98. int main() {
  99. #ifndef ONLINE_JUDGE
  100. freopen("in.txt", "r", stdin);
  101. //freopen("out.txt", "w", stdout);
  102. #endif // ONLINE_JUDGE
  103. int n;
  104. init();
  105. while (cin >> n) {
  106. for (int i = ; i <= n; i ++) {
  107. scanf("%d", a + i);
  108. }
  109. scanf("%s", s);
  110. fillchar(dp, );
  111. for (int i = ; i <= n; i ++) dp[i][i] = a[i];
  112. for (int L = ; L <= n; L ++) {
  113. for (int i = ; i + L - <= n; i ++) {
  114. int j = i + L - ;
  115. for (int k = i; k < j; k ++) {
  116. dp[i][j] += get(dp[i][k], s[k - ], dp[k + ][j], fac[k - i], fac[j - k - ]) * fac[j - i - ] * facinv[k - i] * facinv[j - k - ];
  117. }
  118. }
  119. }
  120. printf("%d\n", dp[][n].get());
  121. }
  122. return ;
  123. }

[hdu5396 Expression]区间DP的更多相关文章

  1. hdu5396 Expression 区间dp +排列组合

    #include<stdio.h> #include<string> #include<map> #include<vector> #include&l ...

  2. hdu 5396 Expression(区间dp)

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

  3. 2015暑假多校联合---Expression(区间DP)

    题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=5396 Problem Description Teacher Mai has n numb ...

  4. 【区间dp+组合数+数学期望】Expression

    https://www.bnuoj.com/v3/contest_show.php?cid=9148#problem/I [题意] 给定n个操作数和n-1个操作符,组成一个数学式子.每次可以选择两个相 ...

  5. CF149D. Coloring Brackets[区间DP !]

    题意:给括号匹配涂色,红色蓝色或不涂,要求见原题,求方案数 区间DP 用栈先处理匹配 f[i][j][0/1/2][0/1/2]表示i到ji涂色和j涂色的方案数 l和r匹配的话,转移到(l+1,r-1 ...

  6. Code Forces 149DColoring Brackets(区间DP)

     Coloring Brackets time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  7. BZOJ 2101 [Usaco2010 Dec]Treasure Chest 藏宝箱:区间dp 博弈【两种表示方法】【压维】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2101 题意: 共有n枚金币,第i枚金币的价值是w[i]. 把金币排成一条直线,Bessie ...

  8. hdu5396 Expression

    Expression Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  9. CF 149D Coloring Brackets(区间DP,好题,给配对的括号上色,求上色方案数,限制条件多,dp四维)

    1.http://codeforces.com/problemset/problem/149/D 2.题目大意 给一个给定括号序列,给该括号上色,上色有三个要求 1.只有三种上色方案,不上色,上红色, ...

随机推荐

  1. mybatis源码配置文件解析之三:解析typeAliases标签

    在前边的博客在分析了mybatis解析settings标签,<mybatis源码配置文件解析之二:解析settings标签>.下面来看解析typeAliases标签的过程. 一.概述 在m ...

  2. 转载-linux内核长什么样

    来源:Linux中国 今天,我来为大家解读一幅来自 TurnOff.us 的漫画 "InSide The Linux Kernel" . TurnOff.us是一个极客漫画网站,作 ...

  3. alfred workflow 开发

    alfred python demo

  4. java算法-二分法查找实现

    什么是二分法查找 首先,使用二分法查找的前提是:被查找的数组已排好序 具体实现: 假如有一组数为3,12,24,36,55,68,75,88要查给定的值24.可设三个变量front,mid,end分别 ...

  5. Task启动方式及源码探究

    启动Task有几种方式: 1.Task.Run() 2.new TaskFactory.StartNew() 3.var t=new Task();  t.start(); 平时用的最多是第一和第二种 ...

  6. 字符串translate方式实现

    在爬取百度图片的时候,发现百度图片做了反爬虫处理,在网上找到当前还能跑通的教程实例:python3多线程下载百度图片搜索结果. 在分析代码的过程中,发现作者对爬取的objURL的解码是通过字符串的tr ...

  7. CSS开发技巧(四):解决flex多行布局的行间距异常、子元素高度拉伸问题

    在使用flex布局时,若出现换行,有两种较为特殊的现象是值得我们研究的: 子元素高度被拉伸,其实际高度大于它的内容高度. 各行子元素之间的行间距过大,甚至我们根本没有给子元素设置margin. 现在我 ...

  8. Vant Weapp小程序蹲坑之使用card组件显示价格

    问题 在基于mpvue+Vant Weapp组件库实战过程中,问题越来越多.网络上所谓的"坑"总结,仅仅不过是其开发中所遭所遇之"坑"而已--估计后面的&quo ...

  9. 【总结】Centos中,Kerberos安装

    1.安装软件包 安装必须的工具 bison, make, binutils 下载压缩包至/usr/local目录下,并解压 [root@localhost local]# ls krb5-1.14.t ...

  10. CodeForces-1058B B. Vasya and Cornfield

    这题,我真的不知道题解是啥,自己看代码吧. #include<iostream> using namespace std; int main() { int n, d,m,i,x,y; c ...