[组合数学][计数DP]JZOJ 4254 集体照
分析
组合数学题日常博客跳转
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> using namespace std; typedef long long ll; const int N=5e2+10; const int Sigma=1.5e3+10; const ll P=1e9+7; int n; ll a[N],s[N],fact[N],C[Sigma][Sigma],f[N][Sigma]; int main() { freopen("photo.in","r",stdin);freopen("photo.out","w",stdout); scanf("%d",&n); fact[0]=C[0][0]=1; for (int i=1;i<N;i++) fact[i]=fact[i-1]*i%P; for (int i=1;i<Sigma;i++) for (int j=0;j<=i;j++) C[i][j]=(C[i-1][j]+(j?C[i-1][j-1]:0))%P; for (int i=1;i<=n;i++) scanf("%lld",&a[i]),s[i]=s[i-1]+a[i]; f[1][s[1]-1]=1; for (int i=2;i<=n;i++) for (int j=0;j<=s[i-1];j++) if (f[i-1][j]) for (int k=1;k<=a[i];k++) for (int t=0;t<=min(k,j);t++) (f[i][j+a[i]-k-t]+=f[i-1][j]*C[j][t]%P*C[a[i]-1][k-1]%P*C[s[i-1]+1-j][k-t]%P)%=P; for (int i=1;i<=n;i++) (f[n][0]*=fact[a[i]])%=P; printf("%lld\n",f[n][0]); }
在日渐沉没的世界里,我发现了你。