码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5396 Expression

时间:2015-08-18 22:54:15      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:dp   c语言   区间dp   

传送门
区间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 );
    }
}

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

HDU 5396 Expression

标签:dp   c语言   区间dp   

原文地址:http://blog.csdn.net/oilover/article/details/47760165

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!