【NOIP2014模拟10.25A组】放棋子

来源:互联网 发布:自制西门子编程线 编辑:程序博客网 时间:2024/05/22 02:28

Description

这里写图片描述

Solution

首先要保证每行每列至少要有一个,那么就容斥一下,枚举有多少行或列没有选。
因为枚举选不选行和列是相对独立的,那么假设枚举了i行,j列,那么要知道容斥系数(1)(i+j)
然后枚举i,j之后,需要知道选出来的方案数CinCjm
然后在剩下的行中随便搞,有两种方案:1、可以不填,2、不能不填
fjiij()
f[i][j]=f[i1][j1]+f[i1][j]j
1、(c+1)!fc+1(ni)(mj)加上一个c+1的颜色(空格),然后(c+1)中颜色再全排列。
2、c!fc(ni)(mj)原来的c种颜色,然后再全排列。
最后答案就是

i=0nj=0mCinCjm((c+1)!fc+1(ni)(mj)+c!fc(ni)(mj))

Code

#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#define fo(i,a,b) for(i=a;i<=b;i++)#define fod(i,a,b) for(i=a;i>=b;i--)using namespace std;typedef long long ll;const int maxn=403,mo=1e9+7;ll i,j,k,l,t,n,m,ans,c,fu;ll fact[maxn],ni[maxn];int f[maxn*maxn][maxn];ll qsm(ll x,ll y){    ll z=1;    for(;y;y/=2,x=x*x%mo)if(y&1)z=z*x%mo;    return z;}ll cc(ll x,ll y){return fact[x]*ni[y]%mo*ni[x-y]%mo;}int main(){    fact[0]=ni[0]=1;    fo(i,1,400)fact[i]=fact[i-1]*i%mo;ni[400]=qsm(fact[400],mo-2);    fod(i,399,1)ni[i]=ni[i+1]*(i+1)%mo;    scanf("%d%d%d",&n,&m,&c);    f[0][0]=1;    fo(i,1,n*m){        fo(j,1,min(c+1,i)){            f[i][j]=(ll)(f[i-1][j-1]+f[i-1][j]*j%mo)%mo;        }    }    fo(i,0,n){        fo(j,0,m){            fu=((i+j)%2)?-1:1;            ans=(ans+cc(n,i)*cc(m,j)%mo*fu*(f[(n-i)*(m-j)][c+1]*fact[c+1]%mo+f[(n-i)*(m-j)][c]*fact[c]%mo)%mo)%mo;        }    }    ans=(ans+mo)%mo;    printf("%lld\n",ans);}
1 0
原创粉丝点击