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个符号,也就是有(j-l)!种不同的运算序列,dp[j+1][r]有(r-j-1)!种运算序列,那么对于不同的运算序列得到的值应该累加,所以累加的和为dp[l][j]*(r-j-1)! + dp[j+1][r]*(j-l),同时还要注意,这种运算序列是符号j的左右两侧分开考虑的,如果交叉考虑,只要各自相对的运算顺序没变,那么值就不会变,但会形成新的一种运算方法,所以最终的值还要再乘以C(r-l-1
, j-l  )。

2、‘-‘

和加法基本相同,只需要把加换成减。

3、‘*‘

对于乘法,我们需要的结果是左右表达式中的各种运算方式得到的值分别相乘然后累加和,这个结果就可以直接转化为dp[l][j]*dp[j+1][r],同样我们还需要对最终的结果乘以C(r-l-1 , j-l)

注意取余,最终的dp[0][n-1]就是结果

#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <cmath>
#include <map>
#include <stack>
#include <time.h>
#include <algorithm>
using namespace std ;
#pragma comment(linker, "/STACK:102400000,102400000")
#define LL __int64
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int Mod = 1e9+7;
LL c[110][110] , s[110] ;
LL a[110] ;
LL dp[110][110] ;
char str[110] ;
void init() {
    int i , j ;
    for(i = 0 ; i <= 100 ; i++) {
        c[i][0] = c[i][i] = 1 ;
        for(j = 1 ; j < i ; j++)
            c[i][j] = (c[i-1][j]+c[i-1][j-1])%Mod ;
    }
    for(i = 1 , s[0] = 1 ; i <= 100 ; i++)
        s[i] = s[i-1]*i%Mod ;
    return ;
}
int main() {
    init() ;
    int n , i , j , len , l , r ;
    while( scanf("%d", &n) != EOF ) {
        for(i = 0 ; i < n ; i++)
            scanf("%I64d", &a[i]) ;
        scanf("%s", str) ;
        memset(dp,0,sizeof(dp)) ;
        for(i = 0 ; i < n ; i++) dp[i][i] = a[i] ;
        for(len = 2 ; len <= n ; len++) {
            for(i = 0 ; i+len-1 < n ; i++) {
                l = i ; r = i+len-1 ;
                for(j = l ; j < r ; j++) {
                    if( str[j] == '+' ) {
                        dp[l][r] = ( dp[l][r] + (dp[l][j]*s[r-(j+1)]%Mod+dp[j+1][r]*s[j-l]%Mod)*c[r-l-1][j-l]%Mod ) ;
                        dp[l][r] = (dp[l][r]%Mod+Mod)%Mod ;
                    }
                    else if( str[j] == '-' ) {
                        dp[l][r] = ( dp[l][r] + (dp[l][j]*s[r-(j+1)]%Mod-dp[j+1][r]*s[j-l]%Mod)*c[r-l-1][j-l]%Mod ) ;
                        dp[l][r] = (dp[l][r]%Mod+Mod)%Mod ;
                    }
                    else if( str[j] == '*' ) {
                        dp[l][r] = (dp[l][r] + dp[l][j]*dp[j+1][r]%Mod*c[r-l-1][j-l]%Mod) ;
                        dp[l][r] = (dp[l][r]%Mod+Mod)%Mod ;
                    }
                }
            }
        }
        printf("%I64d\n", dp[0][n-1]) ;
    }
    return 0 ;
}

版权声明:转载请注明出处:http://blog.csdn.net/winddreams

时间: 2024-08-06 07:38:44

hdu5396(2015多校9)--Expression(区间dp)的相关文章

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

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+

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

HDU 5378 Leader in Tree Land(2015 多校第7场 dp)

Leader in Tree Land Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 150    Accepted Submission(s): 54 Problem Description Tree land has  cities, connected by  roads. You can go to any city from

HDU 5375(2015多校7)-Gray code(dp)

题目地址:HDU 5375 题意:给你一个二进制串,带'?'的位置可以由你来决定填'1'还是'0',补充完整之后转换成格雷码表示,每一个位置都有一个权值a[i],只有格雷码为'1'的位可以加上权值,问你最终权值之和最大为多少. 思路:首先要明白二进制码和格雷码是如何转换的: dp[i][0]表示第i位为0的时候的最大值,dp[i][1]表示第i位为1的时候的最大值.对于第i位的最大值由dp[i-1][0],dp[i-1][1]和当前权值a[i]得到.当前的位的二进制码有0,1,?三种情况,所以就

2015暑假多校联合---Expression(区间DP)

题目链接 http://acm.split.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 wan

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],因为乘法分配律可以保证所有的答案都会乘起来.如果是加法,需要加的 就是 左边的答案 乘 右边操作数的阶乘 加上 右边的答案乘左边操作数的阶乘,最后要确定左边操作和右边操作的顺序 因为每个答案里是统计了该区间所有的阶乘情况,因此

2015 UESTC Training for Dynamic Programming A- 男神的礼物(区间dp)

A - 男神的礼物 Time Limit: 3000/3000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status Lweb学长是集训队里公认的男神.有一天他要给美美的学姐姐准备礼物. Lweb学长可是会魔法的哟.为了准备一份礼物,男神要加工n份材料.每一次只能加工相邻的材料. 当男神加工两个魔法值为a,b的材料,男神都要消耗a*b的体力,同时在这个地方合成出魔法值(a+b)%100的材料. 男神

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]这段里面能形成的答案的总

hdu5289||2015多校联合第一场1002贪心+RMQ

http://acm.hdu.edu.cn/showproblem.php?pid=5289 Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered from 1 to n in this company, and every staff has a ability. Now, Tom is going to assign a special task to