zoukankan      html  css  js  c++  java
  • 2015 Multi-University Training Contest 9 hdu 5396 Expression

    Expression

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


    Problem Description
    Teacher Mai has n numbers $a_1,a_2,dots,a_n$ and $n-1$ operators ("+","-" or "*")$op_1,op_2,dots,op_{n-1}$ which are arranged in the form $a_1quad op_1 quad a_2quad op_2quad a_3dotsquad a_n$

    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(2leq n leq 100)$.

    The second line contains n integers $a_1,a_2,⋯,a_nquad(0≤a_i leq 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.
     
    Author
    xudyh
     
    Source
     
    解题:区间动规,尼玛,最坑爹的地方在于区间合并的时候容易把合并也是有时序的忘记乘入了。
     
    c[t-j-1][k-j]就是干这个用的 假设左边的顺序固定,右边的顺序固定,合并后,还得保持来自左边的那些操作符的相对操作顺序,右边的也一样,所以是组合数
     
    关于阶乘,其实这么多个操作符,有多少种操作顺序?当然是阶乘个
     
    至于+-法的合并,可以发现假设A代表里面有3个和的和,B代表里面有2个和的和
     
    A(a,b,c) + B(d+e)
     
    由于我们要求每种可能
     
    那么将产生 
     
    $a + d quad b + d quad c + d$
    $a + e quad b + e quad c + e$
     
    可以发现其等价于 2A + 3B A里面的元素都加了两次,B里面的元素都加了3次
     
    好啦dp吧,没想到要用到$inom{0}{0}$害我debug好久
     
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int maxn = 110;
     5 const LL mod = 1000000007;
     6 LL dp[maxn][maxn],c[maxn][maxn] = {1},f[maxn] = {1};
     7 void init() {
     8     for(int i = 1; i < maxn; ++i) {
     9         c[i][0] = c[i][i] = 1;
    10         f[i] = f[i-1]*i%mod;
    11         for(int j = 1; j < i; ++j)
    12             c[i][j] = (c[i-1][j-1] + c[i-1][j])%mod;
    13     }
    14 }
    15 char op[maxn];
    16 int main() {
    17     init();
    18     int n;
    19     while(~scanf("%d",&n)) {
    20         memset(dp,0,sizeof dp);
    21         for(int i = 0; i < n; ++i)
    22             scanf("%I64d",&dp[i][i]);
    23         scanf("%s",op);
    24         for(int i = 2; i <= n; ++i) {
    25             for(int j = 0; j + i <= n; ++j) {
    26                 for(int k = j,t = j + i -1; k < t; ++k) {
    27                     LL tmp;
    28                     if(op[k] == '+')
    29                         tmp = (f[t-k-1]*dp[j][k] + f[k-j]*dp[k+1][t])%mod;
    30                     else if(op[k] == '-') {
    31                         tmp = (f[t-k-1]*dp[j][k] - f[k-j]*dp[k+1][t])%mod;
    32                         tmp = (tmp + mod)%mod;
    33                     } else if(op[k] == '*') tmp = dp[j][k]*dp[k+1][t]%mod;
    34                     tmp = tmp*c[t-j-1][k-j]%mod;
    35                     dp[j][t] = (dp[j][t] + tmp + mod)%mod;
    36                 }
    37             }
    38         }
    39         printf("%I64d
    ",dp[0][n-1]);
    40     }
    41     return 0;
    42 }
    View Code
     
  • 相关阅读:
    学习两个Python不常用的语法
    使用uwsgi在centos7上部署Flask在线Web服务
    redis server学习002
    上传至gitlab—— 本地git出现fatal: The current branch develop has no upstream branch. To push the current branch and set the remote as upstream, use git push --set-upstream origin develop 的问题
    数据库脏数据——数据库中的并发操作带来的一系列问题
    error: failed to push some refs to 'git@github.com:Sirxy/flask_jwt_demo.git'
    redis server学习001
    【解决方案】麒麟v10,更新yum源
    【解决方案】github图片加载不出来
    linux c程序高cpu,排查记录
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4740601.html
Copyright © 2011-2022 走看看