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/ ...
随机推荐
- To the world you may be one person, but to one person you may be the world.
To the world you may be one person, but to one person you may be the world.对于世界而言,你是一个人:但对于某人而言,你是他的 ...
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur
屠龙宝刀点击就送 Tarjan缩点+拓扑排序 以后缩点后建图看n范围用vector ,或者直接用map+vector 结构体里数据要清空 代码: #include <cstring> #i ...
- ABAP和Java单例模式的攻防
ABAP CLASS zcl_jerry_singleton DEFINITION PUBLIC FINAL CREATE PRIVATE . PUBLIC SECTION. INTERFACES i ...
- 日常-acm-子序列的和
输入两个正整数n<m<10^6,输出,保留五位小数.输入包含多组数据,结束标记为n=m=0. 样例输入: 2 4 65536 655360 0 0 样例输出: Case 1:0.42361 ...
- Android(java)学习笔记134:Android数据存储5种方式总结
1.使用文件(File)存储 存储一般的数据 2.使用sharedperference(xml) 存储设置信息.配置信息.密码 3.数据库Sqlite 开源的,嵌入式的数据库,轻量级 4.使用Cont ...
- C#之winform实现文件拖拽功能【转】
将一个文件拖拽到窗体的某个控件时,将该控件的路径显示在该控件上,只要拿到了路径自然可以读取文件中的内容了 将一个控件的属性AllowDrop设置为true,然后添加DragDrop.DragEnter ...
- 使用MaskedTextBox控件实现输入验证
实现效果: 知识运用: MaskedTextBox控件的 Mask属性 BeepOnError属性 MaskInputRejected事件 实现代码: private void Form1_Load( ...
- bootstrap 翻页的状态
翻页的状态 下面的实例演示了上表中所讨论的 class .disabled 的用法: <!DOCTYPE html><html><head><meta htt ...
- C#数组协方差
对于任意两个“引用类型”A和B,如果存在从A到B的隐式引用转换或显式引用转换,则也一定存在从数组类型A[R]到数组类型B[R]的相同的引用转换,其中R可以是任何给定的“秩说明符”,但是这两个数组类型必 ...
- 作业题:闰年 if((year%4==0&&year%100!=0)||year&400==0)
作业题:闰年 if((year%4==0&&year%100!=0)||year&400==0)