Codeforces Round #277.5 (Div. 2)-F. Special Matrices

原題鏈接

F. Special Matrices
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

An n × n square matrix is special, if:

  • it is binary, that is, each cell contains either a 0, or a 1;
  • the number of ones in each row and column equals 2.

You are given n and the first m rows of the matrix. Print the number of special n × n matrices, such that the first m rows coincide with the given ones.

As the required value can be rather large, print the remainder after dividing the value by the given number mod.

Input

The first line of the input contains three integers nmmod (2 ≤ n ≤ 5000 ≤ m ≤ n2 ≤ mod ≤ 109). Then m lines follow, each of them contains n characters — the first rows of the required special matrices. Each of these lines contains exactly two characters '1', the rest characters are '0'. Each column of the given m × n table contains at most two numbers one.

Output

Print the remainder after dividing the required value by number mod.

Examples
input
3 1 1000
011
output
2
input
4 4 100500
0110
1010
0101
1001
output
1
dp[i][j]表示0到i行有j個列只有1個1的情況,總共有cnt = (i + 1) * 2個1, 所以有s1 = (cnt - j) / 2個列有2個1,s2= n - j - s1個列沒有1

1.在沒有1的列中取兩個列在i+1行分別放一個1

dp[i+1][j+2] += dp[i][j] * s2 * (s2 -1) / 2

2.在有1個1的列中去兩列在i+1行分別放1

dp[i+1][j-2] += dp[i][j] * j * (j-1) / 2

3.在有1個1的列和沒有1的中分別取1個列在i+1行分別放1

dp[i+1][j] += dp[i][j] * s2 * j

#include <bits/stdc++.h>
#define maxn 505
using namespace std;
typedef long long ll;

char str[maxn][maxn], vis[maxn];
ll dp[maxn][maxn];
int main() {
//	freopen("in.txt", "r", stdin);
	int n, m, mod;
	scanf("%d%d%d", &n, &m, &mod);
	for(int i = 0; i < m; i++)
	 scanf("%s", str[i]);
	if(m) {
		for(int i = 0; i < n; i++)
		 for(int j = 0; j < m; j++) {
		 	if(str[j][i] == '1')
		 	 vis[i]++;
		 }
	}
	int cnt = m * 2, k = 0;
	for(int i = 0; i < n; i++)
	  if(vis[i] == 1)
	   k++;
	if(m)
	 dp[m-1][k] = 1;
	else {
		dp[0][2] = n * (n - 1) / 2;
		m = 1;
		cnt = 2;
	}
	for(int i = m-1; i < n-1; i++) {
		for(int j = 0; j <= 500; j++) {
			if(dp[i][j]) {
				int s = n - (j + (cnt - j) / 2);
				if(s >= 2) {
					(dp[i+1][j+2] += dp[i][j] * s * (s-1) / 2) %= mod;
				}
				if(j >= 2) {
					(dp[i+1][j-2] += dp[i][j] * j * (j - 1) / 2) %= mod;
				}
				if(s >= 1 && j >= 1) {
					(dp[i+1][j] += dp[i][j] * s * j) %= mod;
				}
			}
		}
		cnt += 2;
	}
	cout << dp[n-1][0] << endl;
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章