BZOJ 3294: [Cqoi2011]放棋子

Description

Input

输入第一行为两个整数n, m, c,即行数、列数和棋子的颜色数。第二行包含c个正整数,即每个颜色的棋子数。所有颜色的棋子总数保证不超过nm

Output

输出仅一行,即方案总数除以 1,000,000,009的余数。

Sample Input

4 2 2

3 1

Sample Output

8

HINT

N,M<=30 C<=10 总棋子数<=250

Solution

—————Vani

注意答案的统计!

Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int INF = 1<<30;
const LL mod = 1000000009;
int getint() {
	int r = 0, k = 1; char c = getchar();
	for (; '0' > c || c > '9'; c = getchar()) if (c == '-') k = -1;
	for (; '0' <= c && c <= '9'; c = getchar()) r = r * 10 - '0' + c;
	return r * k;
}
int n, m, c, A[15];
LL dp[15][35][35], g[15][35][35], CC[1605][1605];
LL C(int n, int k) {
	return CC[n][k];
}
int main() {
	for (int i = 0; i < 1600; ++i)
		CC[i][0] = 1;
	for (int i = 1; i < 1600; ++i)
		for (int j = 1; j <= i; ++j)
			CC[i][j] = (CC[i-1][j] + CC[i-1][j-1]) % mod;
	n = getint(); m = getint(); c = getint();
	for (int i = 1; i <= c; ++i) A[i] = getint();
	for (int k = 1; k <= c; ++k)
		for (int x = 1; x <= n; ++x)
			for (int y = 1; y <= m; ++y) {
				g[k][x][y] = C(x * y, A[k]);
				for (int i = 1; i <= x; ++i)
					for (int j = 1; j <= y; ++j) {
						if (i == x && j == y) continue;
						g[k][x][y] = (mod + g[k][x][y]-((g[k][i][j] * C(x, i) % mod) * C(y, j))%mod) % mod;
					}
			}
	for (int x = 1; x <= n; ++x)
		for (int y = 1; y <= m; ++y)
			dp[1][x][y] = g[1][x][y];
	for (int k = 2; k <= c; ++k)
		for (int x = 1; x <= n; ++x)
			for (int y = 1; y <= m; ++y)
				for (int i = 0; i < x; ++i)
					for (int j = 0; j < y; ++j)
						dp[k][x][y] = (dp[k][x][y] + ((dp[k-1][i][j] * g[k][x-i][y-j]) % mod * C(x, i) % mod * C(y, j)) % mod) % mod;
	LL ans = 0;
	for (int x = 1; x <= n; ++x)
		for (int y = 1; y <= m; ++y)
			ans = (ans + dp[c][x][y] * CC[n][x] % mod * CC[m][y] % mod) % mod;
	printf("%lld", ans);
}