感觉自己就是不怎么擅长计数的问题
设f[k,i,j]表示前k种颜色占据了i行j列的方案
g[k,i,j]表示第k种颜色占据了i行j列的方案,注意要减去并没占据满i行j列的情况
然后转移就很好写了
像这种题目构造好了状态后都非常好解决
1 const mo=1000000009; 2 var g,f:array[0..11,0..31,0..31] of longint; 3 c:array[0..1010,0..1010] of longint; 4 a:array[0..15] of longint; 5 n,m,i,j,k,q,x,y,ans:longint; 6 7 begin 8 readln(n,m,q); 9 c[0,0]:=1; 10 for i:=1 to n*m do 11 begin 12 c[i,0]:=1; 13 for j:=1 to i do 14 c[i,j]:=(c[i-1,j]+c[i-1,j-1]) mod mo; 15 end; 16 for i:=1 to q do 17 read(a[i]); 18 for k:=1 to q do 19 for i:=1 to n do 20 for j:=1 to m do 21 begin 22 if (i*j<a[k]) or (i>a[k]) or (j>a[k]) then continue; 23 g[k,i,j]:=c[i*j,a[k]]; 24 for x:=1 to i do 25 for y:=1 to j do 26 if (i-x+j-y)>0 then 27 g[k,i,j]:=(g[k,i,j]-int64(g[k,x,y])*int64(c[i,x]) mod mo*int64(c[j,y]) mod mo+mo) mod mo; 28 end; 29 30 f[0,0,0]:=1; 31 for k:=1 to q do 32 begin 33 a[k]:=a[k]+a[k-1]; 34 for i:=1 to n do 35 for j:=1 to m do 36 begin 37 if i*j<a[k] then continue; 38 for x:=1 to i do 39 for y:=1 to j do 40 f[k,i,j]:=(f[k,i,j]+int64(f[k-1,i-x,j-y])*int64(g[k,x,y]) mod mo*int64(c[i,x]) mod mo*int64(c[j,y]) mod mo) mod mo; 41 end; 42 end; 43 for i:=1 to n do 44 for j:=1 to m do 45 ans:=(ans+int64(f[q,i,j])*int64(c[n,i]) mod mo*int64(c[m,j]) mod mo) mod mo; 46 47 writeln(ans); 48 end.