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;const int MOD=1e9+7;int n;int a[N];char ch[N];void rd(int&x){char ch;for(ch=getchar();ch<'0' || ch>'9';ch=getchar());x=0;for(;ch>='0' && ch<='9';ch=getchar()) x=x*10+ch-'0';}long long res;long long sum[N][N][N]; /*sum[i][j][k]表示区间i到j最后一个取第k个符号的答案和 ,sum[i][j][n+1]表示区间i到的答案总和*/long long A[N];long long calc(long long x,long long y,char c){if(c=='+') return (x+y)%MOD;else if(c=='-') return (x-y+MOD)%MOD;else return (x*y)%MOD;}long long C[N][N];void solve(){memset(sol,0,sizeof sol);memset(sum,0,sizeof sum);for(int i=1;i<=n;i++){sum[i][i][n+1]=a[i];}for(int i=1;i<n;i++){sum[i][i+1][n+1]=sum[i][i+1][i]=calc(a[i],a[i+1],ch[i]);}for(int j=3;j<=n;j++)for(int i=1;i+j-1<=n;i++){int l=i,r=i+j-1;for(int k=l;k<r;k++){if(ch[k]=='+'){/*第k个符号左边 第l到k个数字,这个区间的方案个数 A[k-l]sum[l][k][n+1] l到k的和第k个符号右边 第k+1到r个数字 这个区间的方案个数 A[r-k-1] sum[k+1][r][n+1] k+1到r的和设左边 A[k-l]个值 a1,a2, ……..设右边 A[r-k-1] 个值 b1,b2, ……..(a1+a2……..) + (b1,b2………….)对于每个a,被加A[r-k-1]次 ,,对于每个b,被加A[k-l]次减法同理乘法特殊一点(a1+a2……..) * (b1,b2………….) 乘法分配率,直接将两部分的总和相乘即可*/sum[l][r][k]=(sum[l][k][n+1]*A[r-k-1]+sum[k+1][r][n+1]*A[k-l])%MOD;}else if(ch[k]=='-'){sum[l][r][k]=(sum[l][k][n+1]*A[r-k-1]-sum[k+1][r][n+1]*A[k-l])%MOD;sum[l][r][k]=(sum[l][r][k]+MOD)%MOD;}else{sum[l][r][k]=(sum[l][k][n+1]*sum[k+1][r][n+1])%MOD;}/*之前算的是(左边的选择序列)+(右边的选择序列),但是左右两边也有先后,再乘个组合数,比赛时这个想了好久才想到*/sum[l][r][k]=(sum[l][r][k]*C[r-l-1][k-l])%MOD;sum[l][r][n+1]=(sum[l][r][n+1]+sum[l][r][k])%MOD;sum[l][r][n+1]=(sum[l][r][n+1]+MOD)%MOD;}}printf("%I64d\n",sum[1][n][n+1]);}int main(){#ifndef ONLINE_JUDGEfreopen("aaa","r",stdin);#endifint T;int q;A[0]=1;/*A是全排列 C是组合 ,预处理这两个*/for(int i=1;i<N;i++) A[i]=(A[i-1]*i)%MOD;for(int i=0;i<N;i++) C[i][0]=1;for(int i=1;i<N;i++) for(int j=0;j<=i;j++) {if(j==0 || j==i) C[i][j]=1;else C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD;}while(~scanf("%d",&n)){for(int i=1;i<=n;i++) scanf("%d",&a[i]);scanf("%s",ch+1);solve();}return 0;}

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

累死累活不说,走马观花反而少了真实体验,

hdu5396 Expression 区间dp +排列组合

相关文章:

你感兴趣的文章:

标签云: