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/ ...
随机推荐
- ASP.Net 页面和后台执行的先后顺序
后台的Page_Load事件——>前台页面加载
- MySQL 如何在一个语句中更新一个数值后返回该值 -- 自增长种子竞态问题处理
什么是竞态问题? 假设有一个计数器,首先当前值自增长,然后获取到自增长之后的当前值.自增长后的值有可能被有些操作用来当做唯一性标识,因此并发的操作不能允许取得相同的值. 为什么不能使用使用UPDATE ...
- c# 字符串的首字母大写转换 方法
方法1: s.Substring(0,1).ToUpper()+s.Substring(1); 方法2: s = System.Threading.Thread.CurrentThread.Curr ...
- Hive的HQL(2)
Hive基础(1) Hive的HQL(2) 1. HQL的数据定义,HQL是一种SQL方言,支持绝大部分SQL-92标准.但是和SQL的差异为:不支持行级别的操作,不支持事务等.HQL的语法接近于My ...
- ios 12 xcode10 新升级的编译报错libstdc++.6.0.9 Multiple commands produce
问题一 编译报错 Showing Recent Messages :-1: Multiple commands produce '/Users/duning/Library/Developer/Xco ...
- Postgres 9.11 网络地址类型函数和操作符
9.11. 网络地址类型函数和操作符 Table 9-31 显示了可以用于 cidr 和 inet 的操作符. 操作符 <<,<<= >>,和 >>= ...
- myeclipes出现{Could not create the view: An unexpected except
今天编写代码的时候突然出现了web工程不能部署的情况,后面了解到主要是因为那个myeclipse非正常关闭或者突然断电的情况,我的是属于第一种的,下面整理一下这个解决方法 1.关闭myeclipse ...
- Java 基础案例
1.变量及基本数据类型 案例1:变量声明及赋值 //1.变量的声明 int a; //声明一个整型的变量a int b,c,d; //声明三个整型变量b,c,d //2.变量的初始化 int a = ...
- 《毛毛虫组》【Alpha】Scrum meeting 1
第一天 日期:2019/6/14 1.1 今日完成任务情况以及遇到的问题. 今日完成任务情况: (1)根据数据库设计时的E-R图将创建的表进行检查确保功能的正确实现. (2)进行公共类的设计,设计出程 ...
- MySQL使用INSERT插入多条记录
MySQL使用INSERT插入多条记录,应该如何操作呢?下面就为您详细介绍MySQL使用INSERT插入多条记录的实现方法,供您参考. 看到这个标题也许大家会问,这有什么好说的,调用多次INSERT语 ...