区间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