http://acm.hdu.edu.cn/showproblem.php?pid=4532
细节决定成败呀 ( x * ( y * z ) % mod ) % mod
刚开始想的是 先 ( y * z ) 对 mod 取模 然后再 *x 对mod取模
后来一想不对呀 (y * z ) 要先 *x 后取模呀
脑子短路伤不起呀
dp+数学
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<set> #include<map> #include<vector> #include<queue> #include<stack> #define LL long long using namespace std; const int N=500; const long long MOD = 1000000007; int a[N]; long long dp[N][N]; long long c[N][N]; long long d[N]; int main() { //freopen("data.in","r",stdin); for(int i=0;i<N;++i) for(int j=0;j<=i;++j) { if(j==0||i==j) c[i][j]=1; else c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD; } d[0]=1; for(int i=1;i<N;++i) d[i]=(d[i-1]*i)%MOD; int T; cin>>T; for(int w=1;w<=T;++w) { int n; cin>>n; for(int i=0;i<n;++i) cin>>a[i]; memset(dp,0,sizeof(dp)); dp[0][a[0]-1]=d[a[0]]; int sum=a[0]; for(int i=0;i<n-1;++i) { for(int j=0;j<sum;++j) { if(dp[i][j]>0) { for(int l=0;l<=j&&l<=a[i+1];++l) { for(int r=0;r<=(sum+1-j)&&l+r<=a[i+1];++r) { if(l+r==0) continue; int J=(j-l)+(a[i+1]-l-r); //dp[i+1][J]=(dp[i+1][J]+(dp[i][j]*(c[j][l]*(c[sum+1-j][r]*(d[a[i+1]]*c[a[i+1]-1][l+r-1])%MOD)%MOD)%MOD)%MOD)%MOD; dp[i+1][J]=(((((c[a[i+1]-1][l+r-1]*d[a[i+1]])%MOD*c[sum+1-j][r])%MOD*c[j][l])%MOD*dp[i][j])%MOD+dp[i+1][J])%MOD; } } } } sum+=a[i+1]; } printf("Case %d: ",w); cout<<dp[n-1][0]<<endl; } return 0; }