hdu5396 Expression

Expression

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 952    Accepted Submission(s): 573

Problem Description

Teacher Mai has n

numbers a1,a2,?,an

and n?1

operators("+", "-" or "*")op1,op2,?,opn?1

, which are arranged in the form a1 op1 a2 op2 a3 ? an

.

He wants to erase numbers one by one. In i

-th round, there are n+1?i

numbers remained. He can erase two adjacent numbers and the operator between them, and then put a new number (derived from this one operation) in this position. After n?1

rounds, there is the only one number remained. The result of this sequence of operations is the last number remained.

He wants to know the sum of results of all different sequences of operations. Two sequences of operations are considered different if and only if in one round he chooses different numbers.

For example, a possible sequence of operations for "1+4?6?8?3

" is 1+4?6?8?3→1+4?(?2)?3→1+(?8)?3→(?7)?3→?21

.

Input

There are multiple test cases.

For each test case, the first line contains one number n(2≤n≤100)

.

The second line contains n

integers a1,a2,?,an(0≤ai≤10^9)

.

The third line contains a string with length n?1

consisting "+","-" and "*", which represents the operator sequence.

Output

For each test case print the answer modulo 10^9+7

.

Sample Input

3

3 2 1

-+

5

1 4 6 8 3

+*-*

Sample Output

2

999999689

Hint

Two numbers are considered different when they are in different positions.

一看这样子就像是区间dp

再看看数据肯定是区间dp

f[i][j]表示区间[i,j]一共(j-i)!种运算得到的所有数之和

加减都很简单,枚举区间[i,j]中i到j-1中间最后一个运算符k

如果是加号,f[i][j]+=(f[i][k]*(j-k-1)!+f[k+1][j]*(k-i)!)*C(j-i-1,k-i)

意思就是考虑左右两边的f[i][k],f[k+1][j]对f[i][j]的影响

如果是减号,把上面+改-

乘法不会,orz了某神犇之后才知道

f[i][j]+=f[i][k]*f[k+1][j]*C(j-i-1,k-i)

 1 #include<cstdio>
 2 #include<cstring>
 3 #define LL long long
 4 #define mod 1000000007
 5 inline LL read()
 6 {
 7     LL x=0,f=1;char ch=getchar();
 8     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
 9     while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
10     return x*f;
11 }
12 int c[110][110];
13 LL a[110];
14 char s[110];
15 LL f[110][110];
16 LL jc[110];
17 inline void init()
18 {
19     c[1][1]=1;
20     for (int i=0;i<=100;i++)c[i][0]=1;
21     for (int i=1;i<=100;i++)
22         for (int j=1;j<=i;j++)
23         c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
24     jc[0]=1;
25     for (int i=1;i<=100;i++)jc[i]=jc[i-1]*i%mod;
26 }
27 int n;
28 int main()
29 {
30     init();
31     while (~scanf("%d",&n))
32     {
33         memset(f,0,sizeof(f));
34         for (int i=1;i<=n;i++)a[i]=read();
35         scanf("%s",s+1);
36         for (int i=1;i<=n;i++)f[i][i]=a[i];
37         for (int len=1;len<=n;len++)
38             for (int i=1;i<=n;i++)
39             {
40                 int j=i+len-1;if (j>n)break;
41                 for (int k=i;k<j;k++)
42                 {
43                     if (s[k]==‘+‘)f[i][j]=(f[i][j]+(f[i][k]*jc[j-k-1]+f[k+1][j]*jc[k-i])%mod*c[j-i-1][k-i]%mod)%mod;
44                     if (s[k]==‘-‘)f[i][j]=(f[i][j]+(f[i][k]*jc[j-k-1]-f[k+1][j]*jc[k-i])%mod*c[j-i-1][k-i]%mod+mod)%mod;
45                     if (s[k]==‘*‘)f[i][j]=(f[i][j]+(f[i][k]*f[k+1][j])%mod*c[j-i-1][k-i])%mod;
46                 }
47             }
48         printf("%lld\n",f[1][n]);
49     }
50 }

hdu 5396

时间: 2024-10-12 00:42:13

hdu5396 Expression的相关文章

[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)!]表示从左区间和右区间选择符号的不同方法总数(把左右区间看成整体,那么符号的选择在整体间也有顺序,内部的顺序不用管,那是子问题需要考虑的)

hdu5396 Expression 区间dp +排列组合

#include<stdio.h> #include<string> #include<map> #include<vector> #include<cmath> #include<stdlib.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; const int N=105; cons

hdu5396(2015多校9)--Expression(区间dp)

题目链接:点击打开链接 题目大意:有n个数,和n-1个符号('+','-','*')形成一个表达式,现在问对于不同的运算序列,得到的结果的总和是多少(结果为非负整数,对1e9+7取余) dp[l][r]记录在区间l到r内的各种不同的运算序列的结果的和. 首先长度len是1的时候,dp[i][i] = a[i] 之后dp[l][r] = ∑ ( dp[l][j] 和 dp[j+1][r] 合并而成  ) j为[l,r]范围内的运算符号,那么分三种情况 1.'+' 对于dp[l][j]共有j-l个符

LeetCode 10. Regular Expression Matching

https://leetcode.com/problems/regular-expression-matching/description/ Implement regular expression matching with support for '.' and '*'. '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover

Spring AOP中pointcut expression表达式解析 及匹配多个条件

Pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression"来描述的. Pointcut可以有下列方式来定义或者通过&& || 和!的方式进行组合. args() @args() execution() this() target() @target() within() @within() @annotation 其中 execution 是用的最多的,其格式为: execution(modifiers-pat

Python正则表达式Regular Expression基本用法

资料来源:http://blog.csdn.net/whycadi/article/details/2011046   直接从网上资料转载过来,作为自己的参考.这个写的很清楚.先拿来看看. 1.正则表达式re模块的基本函数. (1)findall函数的用法 findall(rule,target[,flag])是在目标字符串中找到符合规则的字符串.参数说明:rule表示规则,target表示目标字符串,[,flag]表示的是规则选项.返回的结果是一个列表.若没找到符合的,是一个空列表. 如: 因

如何获取Expression Design 4工具与Expression Blend 4工具

在VS2010+C#+WPF 开发项目过程中涉及到界面的布局与设计,网上有人讲采用Expression Design 4与Expression Blend 4工具相当方便, 于是决定试看看,下面将这个过程与大家分享. 一.安装目的 尽管程序员可以使用VS编写XAML代码的方式来构造用户界面,但是对于有设计爱好的用户来说,使用类似Photoshop一样的Expression套件能将 软件美工最大化.设计过程是先使用了Expression Design来设计图形,然后将其导入到Expression

leetcode-Evaluate the value of an arithmetic expression in Reverse Polish Notation

leetcode 逆波兰式求解 Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are+,-,*,/. Each operand may be an integer or another expression. Some examples: ["2", "1", "+", "3", "

Spring AOP中pointcut expression表达式解析

Pointcut 是指那些方法需要被执行"AOP",是由"Pointcut Expression"来描述的. Pointcut可以有下列方式来定义或者通过&& || 和!的方式进行组合. args() @args() execution() this() target() @target() within() @within() @annotation 其中execution 是用的最多的,其格式为: execution(modifiers-patt