[hdu5396 Expression]区间DP
题意:给一个表达式,求所有的计算顺序产生的结果总和
思路:比较明显的区间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放一起的不同排列方法总数。
对花括号里面的'?'分为三种情况:
- '+' 假设左区间有x种可能的方法,右区间有y种可能的方法,由于分配律的存在,左边的所有结果和会重复计算y次,右边的所有结果和会重复计算x次,而左边共(k-l)个符号,右边共(r-k-1)个符号,所以合并后的答案dp[l][r]=dp[l][k]*(r-k-1)!+dp[k+1][r]*(k-l)!
- '-' 与'+'类似
- '*' 由分配律,合并后的答案dp[l][r]=dp[l][k]*dp[k+1][r]
- #pragma comment(linker, "/STACK:10240000")
- #include <map>
- #include <set>
- #include <cmath>
- #include <ctime>
- #include <deque>
- #include <queue>
- #include <stack>
- #include <vector>
- #include <cstdio>
- #include <string>
- #include <cstdlib>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- using namespace std;
- #define X first
- #define Y second
- #define pb push_back
- #define mp make_pair
- #define all(a) (a).begin(), (a).end()
- #define fillchar(a, x) memset(a, x, sizeof(a))
- #define copy(a, b) memcpy(a, b, sizeof(a))
- typedef long long ll;
- typedef pair<int, int> pii;
- typedef unsigned long long ull;
- //#ifndef ONLINE_JUDGE
- void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
- void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
- void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
- while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
- void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
- void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
- void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
- //#endif
- template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
- template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
- const double PI = acos(-1.0);
- const int INF = 1e9 + ;
- const double EPS = 1e-12;
- /* -------------------------------------------------------------------------------- */
- template<int mod>
- struct ModInt {
- const static int MD = mod;
- int x;
- ModInt(ll x = ): x(x % MD) {}
- int get() { return x; }
- ModInt operator + (const ModInt &that) const { int x0 = x + that.x; return ModInt(x0 < MD? x0 : x0 - MD); }
- ModInt operator - (const ModInt &that) const { int x0 = x - that.x; return ModInt(x0 < MD? x0 + MD : x0); }
- ModInt operator * (const ModInt &that) const { return ModInt((long long)x * that.x % MD); }
- ModInt operator / (const ModInt &that) const { return *this * that.inverse(); }
- ModInt operator += (const ModInt &that) { x += that.x; if (x >= MD) x -= MD; }
- ModInt operator -= (const ModInt &that) { x -= that.x; if (x < ) x += MD; }
- ModInt operator *= (const ModInt &that) { x = (long long)x * that.x % MD; }
- ModInt operator /= (const ModInt &that) { *this = *this / that; }
- ModInt inverse() const {
- int a = x, b = MD, u = , v = ;
- while(b) {
- int t = a / b;
- a -= t * b; std::swap(a, b);
- u -= t * v; std::swap(u, v);
- }
- if(u < ) u += MD;
- return u;
- }
- };
- typedef ModInt<> mint;
- const int maxn = 1e2 + ;
- const int md = 1e9 + ;
- mint dp[maxn][maxn], fac[maxn], facinv[maxn];
- int a[maxn];
- char s[maxn];
- mint get(mint a, char ch, mint b, mint ca, mint cb) {
- if (ch == '+') return a * cb + b * ca;
- if (ch == '-') return a * cb - b * ca;
- if (ch == '*') return a * b;
- }
- void init() {
- fac[] = facinv[] = ;
- for (int i = ; i < maxn; i ++) fac[i] = fac[i - ] * i;
- for (int i = ; i < maxn; i ++) facinv[i] = facinv[i - ] / i;
- }
- int main() {
- #ifndef ONLINE_JUDGE
- freopen("in.txt", "r", stdin);
- //freopen("out.txt", "w", stdout);
- #endif // ONLINE_JUDGE
- int n;
- init();
- while (cin >> n) {
- for (int i = ; i <= n; i ++) {
- scanf("%d", a + i);
- }
- scanf("%s", s);
- fillchar(dp, );
- for (int i = ; i <= n; i ++) dp[i][i] = a[i];
- for (int L = ; L <= n; L ++) {
- for (int i = ; i + L - <= n; i ++) {
- int j = i + L - ;
- for (int k = i; k < j; k ++) {
- 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 - ];
- }
- }
- }
- printf("%d\n", dp[][n].get());
- }
- return ;
- }
[hdu5396 Expression]区间DP的更多相关文章
- hdu5396 Expression 区间dp +排列组合
#include<stdio.h> #include<string> #include<map> #include<vector> #include&l ...
- hdu 5396 Expression(区间dp)
Problem Description Teacher Mai has n numbers a1,a2,⋯,anand n−1 operators("+", "-&quo ...
- 2015暑假多校联合---Expression(区间DP)
题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=5396 Problem Description Teacher Mai has n numb ...
- 【区间dp+组合数+数学期望】Expression
https://www.bnuoj.com/v3/contest_show.php?cid=9148#problem/I [题意] 给定n个操作数和n-1个操作符,组成一个数学式子.每次可以选择两个相 ...
- CF149D. Coloring Brackets[区间DP !]
题意:给括号匹配涂色,红色蓝色或不涂,要求见原题,求方案数 区间DP 用栈先处理匹配 f[i][j][0/1/2][0/1/2]表示i到ji涂色和j涂色的方案数 l和r匹配的话,转移到(l+1,r-1 ...
- Code Forces 149DColoring Brackets(区间DP)
Coloring Brackets time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- BZOJ 2101 [Usaco2010 Dec]Treasure Chest 藏宝箱:区间dp 博弈【两种表示方法】【压维】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2101 题意: 共有n枚金币,第i枚金币的价值是w[i]. 把金币排成一条直线,Bessie ...
- hdu5396 Expression
Expression Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- CF 149D Coloring Brackets(区间DP,好题,给配对的括号上色,求上色方案数,限制条件多,dp四维)
1.http://codeforces.com/problemset/problem/149/D 2.题目大意 给一个给定括号序列,给该括号上色,上色有三个要求 1.只有三种上色方案,不上色,上红色, ...
随机推荐
- mybatis源码配置文件解析之三:解析typeAliases标签
在前边的博客在分析了mybatis解析settings标签,<mybatis源码配置文件解析之二:解析settings标签>.下面来看解析typeAliases标签的过程. 一.概述 在m ...
- 转载-linux内核长什么样
来源:Linux中国 今天,我来为大家解读一幅来自 TurnOff.us 的漫画 "InSide The Linux Kernel" . TurnOff.us是一个极客漫画网站,作 ...
- alfred workflow 开发
alfred python demo
- java算法-二分法查找实现
什么是二分法查找 首先,使用二分法查找的前提是:被查找的数组已排好序 具体实现: 假如有一组数为3,12,24,36,55,68,75,88要查给定的值24.可设三个变量front,mid,end分别 ...
- Task启动方式及源码探究
启动Task有几种方式: 1.Task.Run() 2.new TaskFactory.StartNew() 3.var t=new Task(); t.start(); 平时用的最多是第一和第二种 ...
- 字符串translate方式实现
在爬取百度图片的时候,发现百度图片做了反爬虫处理,在网上找到当前还能跑通的教程实例:python3多线程下载百度图片搜索结果. 在分析代码的过程中,发现作者对爬取的objURL的解码是通过字符串的tr ...
- CSS开发技巧(四):解决flex多行布局的行间距异常、子元素高度拉伸问题
在使用flex布局时,若出现换行,有两种较为特殊的现象是值得我们研究的: 子元素高度被拉伸,其实际高度大于它的内容高度. 各行子元素之间的行间距过大,甚至我们根本没有给子元素设置margin. 现在我 ...
- Vant Weapp小程序蹲坑之使用card组件显示价格
问题 在基于mpvue+Vant Weapp组件库实战过程中,问题越来越多.网络上所谓的"坑"总结,仅仅不过是其开发中所遭所遇之"坑"而已--估计后面的&quo ...
- 【总结】Centos中,Kerberos安装
1.安装软件包 安装必须的工具 bison, make, binutils 下载压缩包至/usr/local目录下,并解压 [root@localhost local]# ls krb5-1.14.t ...
- CodeForces-1058B B. Vasya and Cornfield
这题,我真的不知道题解是啥,自己看代码吧. #include<iostream> using namespace std; int main() { int n, d,m,i,x,y; c ...