HDU 5396 Expression

传送门

区间DP,枚举最后一步操作k,对乘法,答案为

dp[i,k]?dp[k+1,r],由于分配率这个会乘开来。

如果是加法那么是dp[i][k]?(j?k?1)!+dp[k+1][j]?(k?i)!,减法同理。

最后还要乘以C(j?i?1,k?i)

#include <bits/stdc++.h>
using namespace std;
#define prt(k) cerr<<#k" = "<<k<<endl
typedef long long ll;
typedef long long LL;
const ll mod = 1e9 + 7;
const int  N = 233;
ll a[N];
char op[N];
ll dp[N][N];
int n;

ll f[N];
ll C[N][N];
int main()
{
    for (int i=0;i<N;i++)
    for (int j=0;j<=i;j++) {
        if (i==j ||j==0) C[i][j] = 1;
        else C[i][j] = (C[i-1][j-1] + C[i-1][j]) % mod;
    }
    f[0] = 1;
    for (int i=1;i<N;i++) f[i] = f[i-1] * i % mod;
    while (scanf("%d", &n)==1) {
        memset(dp, 0, sizeof dp);
        for (int i=1;i<=n;i++) scanf("%I64d", &dp[i][i]);
        scanf("%s", op+1);
        for (int L = 2; L <= n; L ++)
        for (int i=1;i+L-1<=n;i++) {
            int j = i + L - 1;
            dp[i][j] = 0;
            for (int k=i;k<j;k++) {
                ll t;
                if (op[k]==‘*‘)
                    t = dp[i][k] * dp[k+1][j] % mod;
                if (op[k]==‘+‘)
                    t = (dp[i][k]*f[j-k-1] + dp[k+1][j] * f[k-i])%mod;
                if (op[k]==‘-‘)
                    t = (dp[i][k]*f[j-k-1] - dp[k+1][j] * f[k-i] )%mod;

                dp[i][j] = (dp[i][j] + t * C[j-i-1][k-i]) % mod;
            }
        }
        printf("%I64d\n", (dp[1][n] + mod) %mod );
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-01 10:50:02

HDU 5396 Expression的相关文章

HDU 5396 Expression (MUT#9 区间DP)

[题意]:click here~~ [题目大意]: 给你一个一行包含n(2=<n<=100)个数字的式子,和一个字符串(2=<s<=100),字符串里包含三种运算符号:+,-,*,且s=n-1,也就是说在每两个数字之间,插入n-1个符号,位置已经在输入的时候固定了,现在你要做的就是可以自由安排符号的运算顺序,每轮选择之后,将会得到一个结果,求所有的结果的和 [思路]:区间DP: 先贴一下题解(感觉题解有个地方写错了): 设DP[l][r]:表示区间[l,r]这段里面能形成的答案的总

HDU 5396 Expression (区间DP)

链接 : http://acm.hdu.edu.cn/showproblem.php?pid=5396 设d[i][j] 代表i~j的答案.区间DP枚举(i, j)区间的断点,如果断点处的操作符是'*',那么该区间的答案可以直接加上d[i][k] *  d[k+1][j],因为乘法分配律可以保证所有的答案都会乘起来.如果是加法,需要加的 就是 左边的答案 乘 右边操作数的阶乘 加上 右边的答案乘左边操作数的阶乘,最后要确定左边操作和右边操作的顺序 因为每个答案里是统计了该区间所有的阶乘情况,因此

hdu 5396 Expression(区间dp)

Problem Description Teacher Mai has n numbers a1,a2,?,anand 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+

HDU 5396 Expression(DP+组合数)(详解)

题目大意: 给你一个n然后是n个数. 然后是n-1个操作符,操作符是插入在两个数字之间的. 由于你不同的运算顺序,会产生不同的结果. 比如: 1 + 1 * 2 有两种  (1+1)*2   或者  1+(1*2) 1 *  2 * 3  也是两种即使结果是一样的  (1*2)*3  或者 1*(2*3) 问这所有不同的组合加起来的和对 1e9+7取余是多少. 这个其实就是区间DP了 dp[i][j] 代表的是区间  i 到 j 的和 枚举dp[i][j] 之间所有的子区间 假如是乘法: t =

hdu 5396 区间dp+组合

http://acm.hdu.edu.cn/showproblem.php?pid=5396 Problem Description Teacher Mai has n numbers a1,a2,?,anand n?1 operators("+", "-" or "*")op1,op2,?,opn?1, which are arranged in the form a1 op1 a2 op2 a3 ? an. He wants to erase

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 个运算符. 而且左

hdu 5396 区间DP

Expression Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 482    Accepted Submission(s): 284 Problem Description Teacher Mai has n numbers a1,a2,?,anand n?1 operators("+", "-" o

HDOJ 5396 Expression DP

记dp_{l,r}dp?l,r??表示l,rl,r这段数能形成的答案总和. 枚举最后一步操作kk,如果是乘法,答案为dp_{l,k}*dp_{k+1,r}dp?l,k???dp?k+1,r??,由于分配率这个会乘开来.如果是加法那么是dp_{l,r}*(r-k-1)!+dp_{k+1,r}*(k-l)!dp?l,r???(r?k?1)!+dp?k+1,r???(k?l)!,即要乘上右边k+1,rk+1,r这些数所有可行的方案数,减法同理.最后乘上{r-l-2 \choose k-l}(?k?l?

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("+", "-" o