[BZOJ4487][JSOI2015]染色问题(容斥)
一开始写了7个DP方程,然后意识到这种DP应该都会有一个通式。
三个条件:有色行数为n,有色列数为m,颜色数p,三维容斥原理仍然成立。
于是就是求:$\sum_{i=0}^{n}\sum_{j=0}^{m}\sum_{k=0}^{p}(-1)^{n+m+p-i-j-k}\times C_n^i\times C_m^j\times C_p^k\times (k+1)^{ij}$
复杂度$O(n^3)$
可以根据二项式定理优化:
https://blog.csdn.net/werkeytom_ftd/article/details/52527740
复杂度$O(n^2\log)$
1 #include<cstdio> 2 #include<algorithm> 3 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 4 using namespace std; 5 6 const int N=410,mod=1e9+7; 7 int n,m,p,ans,fac[N],inv[N]; 8 9 int ksm(int a,int b){ 10 int res=1; 11 for (; b; a=1ll*a*a%mod,b>>=1) 12 if (b & 1) res=1ll*res*a%mod; 13 return res; 14 } 15 16 int C(int n,int m){ return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod; } 17 18 int main(){ 19 freopen("bzoj4487.in","r",stdin); 20 freopen("bzoj4487.out","w",stdout); 21 scanf("%d%d%d",&n,&m,&p); 22 fac[0]=1; rep(i,1,400) fac[i]=1ll*fac[i-1]*i%mod; 23 inv[400]=ksm(fac[400],mod-2); 24 for (int i=399; ~i; i--) inv[i]=1ll*inv[i+1]*(i+1)%mod; 25 rep(i,0,n) rep(k,0,p){ 26 int t=1ll*C(n,i)*C(p,k)%mod*ksm((1-ksm(k+1,i)+mod)%mod,m)%mod; 27 if ((n+m+p-i-k)&1) ans=(ans-t+mod)%mod; else ans=(ans+t)%mod; 28 } 29 printf("%d\n",ans); 30 return 0; 31 }