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;
}


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