HDU 5396 Expression

传送门
区间DP,枚举最后一步操作 k ,对乘法,答案为
dp[i,k]dp[k+1,r] ,由于分配率这个会乘开来。
如果是加法那么是 dp[i][k](jk1)!+dp[k+1][j](ki)! ,减法同理。
最后还要乘以 C(ji1,ki)

#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 );
    }
}

你可能感兴趣的:(dp,C语言,区间DP)