HDU 5396 区间DP 数学 Expression
题意:有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的更多相关文章
- hdu 4283 区间dp
You Are the One Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化
HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...
- HDU 4293---Groups(区间DP)
题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=4293 Problem Description After the regional con ...
- String painter HDU - 2476 -区间DP
HDU - 2476 思路:分解问题,先考虑从一个空串染色成 B串的最小花费 ,区间DP可以解决这个问题 具体的就是,当 str [ l ] = = str [ r ]时 dp [ L ] [ R ] ...
- HDU 4632 区间DP 取模
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4632 注意到任意一个回文子序列收尾两个字符一定是相同的,于是可以区间dp,用dp[i][j]表示原字 ...
- 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) ...
- HDU 4570(区间dp)
E - Multi-bit Trie Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u ...
- hdu 2476 区间dp
题意: 给出两个串s1和s2,一次只能将一个区间刷一次,问最少几次能让s1=s2 例如zzzzzfzzzzz,长度为11,我们就将下标看做0~10 先将0~10刷一次,变成aaaaaaaaaaa 1~ ...
- hdu 4632(区间dp)
Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65535 K (Java/ ...
随机推荐
- 2.语言概述-JavaScript权威指南笔记
上周三的时候交给老板目前的项目第一个迭代回顾会的总结.原本是以综述性的表述方式写的,交给他之后表示程序员不要长篇大论.总结要分为优点缺点期望等等块,每块列出条目,简明扼要的表达出来.这里也用这种风格. ...
- 如何构建多模块的SpringBoot项目
通过阅读本文你将了解到:如何将已有SpringBoot项目改成多模块 & 如何新构建多模块SpringBoot项目 以下示例基于我正在使用的order(订单服务)进行演示,无论你用的是什么项目 ...
- 使用Robot类模拟鼠标、键盘事件
Robot类用于模拟鼠标.键盘事件,生成本机系统输入事件.Robot 的主要用于自动化.自运行的程序和其他需要自动控制鼠标和键盘的程序 相当于实际操作的效果,不仅仅只是生成对应的鼠标.键盘事件.比如R ...
- 使用Calendar来获取当前日期和时间
1 package com.java.test; 2 3 import java.text.SimpleDateFormat; 4 import java.util.Calendar; 5 6 pub ...
- specrate 与specspeed 的区别
What is the difference between a "rate" and a "speed" metric?There are several d ...
- MFC制作简单通讯录程序
学习c++和MFC一段时间了,苦于没有项目实战,所以自己写了一个简单的简单通讯录程序,以前用c#写简单很多,例程是这本书上的实例,我的第一个winform程序也是从这本书上学的,总结c#写的话更简单, ...
- cmd下查询端口占用以及根据进程id名称结束进程
cmd窗口中: C:\Users\insentek>netstat -aon|findstr "1099" TCP 0.0.0.0:1099 0.0.0.0:0 LISTEN ...
- 【转】iOS学习笔记(十七)——文件操作(NSFileManager)
iOS的沙盒机制,应用只能访问自己应用目录下的文件.iOS不像android,没有SD卡概念,不能直接访问图像.视频等内容.iOS应用产生的内容,如图像.文件.缓存内容等都必须存储在自己的沙盒内.默认 ...
- 【vue iview】项目 win10 放在C盘 经常npm install不成功,就是因为 权限问题,把代码目录放到D盘就没事了。
[vue iview]项目 win10 放在C盘 经常npm install不成功,就是因为 权限问题,把代码目录放到D盘就没事了.
- 禁止DataGridView控件中添加和删除行
实现效果: 知识运用: DataGridView控件的AllowUserToAddRows AllowUserDeleteRows和ReadOnly属性 实现代码: private void btn_ ...