CodeForces 489F Special Matrices

题意:

n(500)*n的矩阵  每行每列只有两个1  现在给出前m行  问  有几种合法的矩阵

思路:

只需要考虑每列上有几个1  然后按行扫描  每次维护行内只有2个1  这样就能构造出合法矩阵

那么我们定义dp[i][j][k]表示扫描到第i行有j列是包含1个1的有k列是包含2个1的  这时500^3数组开不下  于是滚动i

那么对于dp[i][j][k]

如果n-j-k>=2  则可以选择两列分别填1  即转移到dp[i+1][j+2][k]

如果n-j-k>=1&&j>=1 则可以把某个1的列变成2  同时把0的列变成1  即转移到dp[i+1][j][k+1]

如果j>=2 则可以选择两个1变成2  即转移到dp[i+1][j-2][k+2]

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<bitset>
using namespace std;
typedef long long LL;
#define N 510

int n, m, mod;
int dp[2][N][N];
int num[N];
char s[N];

void add(int &x, int y) {
	x += y;
	if (x >= mod)
		x -= mod;
}

int main() {
	scanf("%d%d%d", &n, &m, &mod);
	for (int i = 1; i <= m; i++) {
		scanf("%s", s + 1);
		for (int j = 1; j <= n; j++) {
			if (s[j] == '1')
				num[j]++;
		}
	}
	int j = 0, k = 0;
	for (int i = 1; i <= n; i++) {
		if (num[i] == 1)
			j++;
		else if (num[i] == 2)
			k++;
	}
	dp[m & 1][j][k] = 1;
	for (int i = m + 1; i <= n; i++) {
		memset(dp[i & 1], 0, sizeof(dp[i & 1]));
		for (j = 0; j <= n; j++) {
			for (k = 0; k + j <= n; k++) {
				if (dp[(i & 1) ^ 1][j][k]) {
					int zero = n - j - k, one = j, two = k;
					LL key = dp[(i & 1) ^ 1][j][k];
					if (zero >= 2)
						add(dp[i & 1][one + 2][two],
								(LL) (zero) * (zero - 1) / 2 % mod * key % mod);
					if (zero >= 1 && one >= 1)
						add(dp[i & 1][one][two + 1],
								key * zero % mod * one % mod);
					if (one >= 2)
						add(dp[i & 1][one - 2][two + 2],
								(LL) (one) * (one - 1) / 2 % mod * key % mod);
				}
			}
		}
	}
	printf("%d\n", dp[n & 1][0][n]);
	return 0;
}
时间: 2024-08-02 21:56:24

CodeForces 489F Special Matrices的相关文章

codeforces 489F Special Matrices(DP)

传送门:点击打开链接 题目大意: 给定一个n*n的01矩阵的前m行,要求求出有多少种构造方案使得:每一行,每一列的1的个数都是2 解题思路: 既然已经给定了前m行,那么就相当于告诉了我们有哪几列,还能放2个1,1个1,和不能再放1了. 注意到,这个时候列之间是可以交换的,那么就可以做了. 定义dp[i][j][k]表示在第i行剩j个位置可以放2个1,剩k个位置可以放1个1. 因为下一行一定要放2个1,那么就有3种转移状态: 1:全部选的是放2个的.那么就转移到了dp[i+1][j-2][k+2]

CodeForces 489F DP Special Matrices

首先统计一下前m行中,有x列1的个数为0,有y列1的个数为1. 设d(i, j)表示有i列1的个数为0,有j列1的个数为1,能到达这个状态的矩阵的个数. 则d(x, y) = 1 每一行都是两个1一起放,枚举这两个1分别放在了哪种列上面 于是有状态转移: d(i - 2, j + 2) += d(i, j) * C(i, 2) d(i - 1, j) += d(i, j) * i * j d(i, j - 2) += d(i, j) * C(j, 2) 1 #include <iostream>

CodeForces 219B Special Offer! Super Price 999 Bourles!

Special Offer! Super Price 999 Bourles! Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 219B Description Polycarpus is an amateur businessman. Recently he was surprised to find out that

Codeforces Gym10008E Harmonious Matrices(高斯消元)

[题目链接] http://codeforces.com/gym/100008/ [题目大意] 给出 一个n*m的矩阵,要求用0和1填满,使得每个位置和周围四格相加为偶数,要求1的数目尽量多. [题解] 首先,如果确定第一排的填法,要求最终结果为偶数,那么就能推出第二排的填法,同理可以依次推出整个矩阵,因此我们设置第一排填法为未知数,可以将方程推到最后一排,因为n+1排填的数字一定是0,这样子就可以得到m个方程.高斯消元求解即可,因为在要求1最多,因此自由变元尽量设为1. [代码] #inclu

Codeforces Round #277.5 (Div. 2) JAVA版题解

Codeforces Round #277.5 (Div. 2) A. SwapSort time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output In this problem your goal is to sort an array consisting of n integers in at most n swaps. For t

基于Linux的视频传输系统(上大学时參加的一个大赛的论文)

文件夹 1原创性声明----------------------------------------------------3 2 摘要----------------------------------------------------------4 3系统方案------------------------------------------------------4 3.1功能与指标----------------------------------------------4 3.2方案

[合集]国庆休闲补题

Hrbust - 1846 题意:序列每个格子允许放O和X,求长度为n的序列中至少存放m个连续的O的方案数 容斥+dp 设\(dp[i]\)为长度为\(i\)时的合法方案数 转移的个数来自于上一个状态的合法序列后面接上O和X,既\(dp[i-1]*2\) 也有可能来自于本来不合法的方案,转移后就合法了,那先固定一部分状态,因为转移后才合法,所以假定序列中[i-m+1,i]全部为O,那么前面就可以为所欲为,有\(2^{i-m}\)个状态,但\(2^{i-m}\)中会有合法方案的存在,因此需要减去已

构造 Codeforces Round #135 (Div. 2) B. Special Offer! Super Price 999 Bourles!

题目传送门 1 /* 2 构造:从大到小构造,每一次都把最后不是9的变为9,p - p MOD 10^k - 1,直到小于最小值. 3 另外,最多len-1次循环 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 using namespace std; 10 11 typedef long long ll; 12 const i

Codeforces 914 C Travelling Salesman and Special Numbers

Discription The Travelling Salesman spends a lot of time travelling so he tends to get bored. To pass time, he likes to perform operations on numbers. One such operation is to take a positive integer x and reduce it to the number of bits set to 1 in