……QwQ做的第一发这种题
f[i][j]表示分配了前i种,至少有j个人不合法,然后容斥一下就好
最后统计的时候,剩下的n-j个人的分配方法是(n-j)!除以每种糖剩余数量的阶乘的积,这个积直接在dp的时候算好
#include<bits/stdc++.h>
#define MOD 1000000009
#define MAXN 2005
using namespace std; int n;
int x[MAXN];
int C[MAXN][MAXN];
int jc[MAXN],_jc[MAXN];
int f[MAXN][MAXN];
inline int POW(long long d,long long c){
long long rtn=1;
for(;c;c>>=1,d=d*d%MOD)
if(c&1) rtn=rtn*d%MOD;
return (int)rtn;
}
inline void Plus(int &a,const int b){
a+=b;
if(a<0) a+=MOD;
if(a>=MOD) a-=MOD;
}
inline void init(){
C[0][0]=1;
for(register int i=1,j;i<=n;++i)
for(j=1,C[i][0]=1;j<=i;++j)
C[i][j]=C[i-1][j-1],Plus(C[i][j],C[i-1][j]);
jc[0]=1;
for(register int i=1;i<=n;++i) jc[i]=1ll*jc[i-1]*i%MOD;
_jc[n]=POW(jc[n],MOD-2);
for(register int i=n-1;~i;--i) _jc[i]=1ll*_jc[i+1]*(i+1)%MOD;
}
int read_x;
int main(){
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
scanf("%d",&n);
init();
for(int i=1;i<=n;++i) scanf("%d",&read_x),++x[read_x];
int tot=0;
f[0][0]=1;
for(int i=1;i<=n;tot+=x[i++])
for(int j=0;j<=tot;++j)
for(int k=0;k<=x[i];++k)
Plus(f[i][j+k],1ll*f[i-1][j]*C[x[i]][k]%MOD*_jc[x[i]-k]%MOD);//,printf("f[ %d ][ %d ] = %d\n",i,j+k,f[i][j+k]);
int ans=0;
// for(int i=0;i<=tot;++i) printf("%d\n",f[n][i]);
for(int i=0;i<=tot;++i)
Plus(ans,(i&1?-1ll:1ll)*f[n][i]*jc[tot-i]%MOD);
printf("%d",ans);
return 0;
}