国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[51NOD1604]對稱的方格顏色

2019-11-08 18:42:54
字體:
來源:轉載
供稿:網友

題目大意

K種顏色對一個n×m的矩形板染色。對于任意一條豎直的線,都能把矩形分成不為空的兩個部分(注意這里是分隔是沿著兩列的交界分隔),要求染色方案滿足每部分中的不同顏色種數要相同。 答案對109+7取模。

1≤n≤1000,2≤m≤1000,1≤K≤106


題目分析

這題剛開始看似乎無從下手,我們要找到一個比較好的突破口來做題。 考慮最左邊和最右邊兩列,它們具有一定的特殊性質。先考慮最左邊一列,可以發現除了最右邊一列,每一列的出現過的顏色都一定在第一列中出現過,這個可以使用反證法來證明:如果存在一種顏色是第一列沒有出現過的,并且假設其左邊的列都是第一列有的顏色,那么從這一列右邊切開,右邊部分的顏色種類數就是第一列的顏色種類數加一,然后我們從這一列左邊切開,可以發現右邊部分的顏色種類數顯然和左邊不一樣。 同理我們可以證明除了最左邊一列,每一列出現過的顏色都一定在最后一列出現過。的確,第一列和最后一列的顏色種類不一定完全相同,中間的列的顏色一定屬于這兩列顏色種類的交集。那么第一列和最后一列的顏色種類數是否相等呢?答案是肯定的。 那么正解就很顯然了,我們令fi,j表示i個格子填j種顏色的方案數,枚舉a為第一列的顏色種類數,b為第一列和最后一列共有的顏色數,那么答案就是 ∑a∑b(K2a?b)(2a?bb)(2(a?b)a?b)(fn,aa!)2bn(m?2) 時間復雜度O(n2)


代碼實現

#include <iostream>#include <cstdio>using namespace std;const int P=1000000007;const int MAXK=1000005;const int N=1005;int fact[MAXK],invf[MAXK];int f[N][N];int n,m,K,ans;int sqr(int x){return 1ll*x*x%P;}int C(int n,int m){return n<m?0:1ll*fact[n]*invf[m]%P*invf[n-m]%P;}int quick_power(int x,int y){ int ret=1; for (;y;x=1ll*x*x%P,y>>=1) if (y&1) ret=1ll*ret*x%P; return ret;}void PRe(){ fact[0]=1; for (int i=1;i<=K;++i) fact[i]=1ll*fact[i-1]*i%P; invf[K]=quick_power(fact[K],P-2); for (int i=K;i>=1;--i) invf[i-1]=1ll*invf[i]*i%P; f[1][1]=1; for (int i=2;i<=n;++i) for (int j=1;j<=i;++j) f[i][j]=(1ll*f[i-1][j]*j%P+f[i-1][j-1])%P;}void calc(){ ans=0; for (int b=0;b<=n;++b) { int t=quick_power(b,n*(m-2)); for (int a=min(K+b>>1,n);a>=b&&a>=1;--a) (ans+=1ll*C(K,2*a-b)*C(2*a-b,b)%P*C(2*(a-b),a-b)%P*sqr(1ll*f[n][a]*fact[a]%P)%P*t%P)%=P; }}int main(){ freopen("color.in","r",stdin),freopen("color.out","w",stdout); scanf("%d%d%d",&n,&m,&K); pre(),calc(); printf("%d/n",ans); fclose(stdin),fclose(stdout); return 0;}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 广水市| 旺苍县| 舞钢市| 社会| 新野县| 吉隆县| 周口市| 扶余县| 农安县| 泸州市| 景洪市| 手游| 浠水县| 新兴县| 元氏县| 绩溪县| 萝北县| 徐水县| 贺兰县| 绿春县| 连云港市| 桃园县| 弋阳县| 措勤县| 七台河市| 纳雍县| 苏尼特左旗| 珠海市| 什邡市| 惠来县| 信丰县| 济南市| 葫芦岛市| 区。| 九江县| 清远市| 太保市| 彭水| 哈尔滨市| 平和县| 新乡县|