Codeforces Round #347 (Div. 1) E. Binary Table ★ ★ ★
来源:互联网 发布:开淘宝店要营业执照吗 编辑:程序博客网 时间:2024/06/07 02:50
题意:给定一个只含01的矩阵,可以把某一行或者某列反转反转,问经过一系列操作最终矩阵最少能剩下几个1
题解:由于n小于20,自然就想到状态压缩,枚举最终状态的第一列,然后贪心处理其他列,不过由于m太大,所以此法不可行,然后,就没有然后了
贴一波官方题解:
First let's examine a slow solution that works in O(2n · m). Since each row can be either inverted or not, the set of options of how we can invert the rows may be encoded in a bitmask of length n, an integer from 0 to (2n - 1), where the i-th bit is equal to 1 if and only if we invert the i-th row. Each column also represents a bitmask of length n (the bits correspond to the values of that row in each of the nrows). Let the bitmask of the i-th column be coli, and the bitmask of the inverted rows be mask. After inverting the rows the i-th column will become . Suppose that contains ones. Then we can obtain either k or (n - k) ones in this column, depending on whether we invert the i-th column itself. It follows that for a fixed bitmask mask the minimum possible number of ones that can be obtained is equal to .
Now we want to calculate this sum faster than O(m). Note that we are not interested in the value of the mask itself, but only in the number of ones it contains (from 0 to n). Therefore we may group the columns by the value of . Let dp[k][mask] be the number of such i that , then for a fixed bitmask mask we can calculate the sum in O(n) — .
What remains is to calculate the value of dp[k][mask] in a quick way. As the name suggests, we can use dynamic programming for this purpose. The value of dp[0][mask] can be found in O(m) for all bitmasks mask: each column coli increases dp[0][coli] by 1. Fork > 0, coli and mask differ in exactly k bits. Suppose mask and coli differ in position p. Then coli and differ in exactly(k - 1) bits. The number of such columns is equal to , except we counted in also the number of columns colithat differ with in bit p (thus, mask and coli have the same value in bit p). Thus we need to subtract dp[k - 2][mask], but again, except the columns among these that differ with mask in bit p. Let ; by expanding this inclusion-exclusion type argument, we get that the number of masks we are interested in can be expressed asdp[k - 1][next] - dp[k - 2][mask] + dp[k - 3][next] - dp[k - 4][mask] + dp[k - 5][next] - .... By summing all these expressions for each bit p from 0 to n, we get dp[k][mask] · k, since each column is counted in k times (for each of the bits p where the column differs frommask).
Therefore, we are now able to count the values of dp[k][mask] in time O(2n · n3) using the following recurrence:
This is still a tad slow, but we can speed it up to O(2n · n2), for example, in a following fashion:
#include <set>#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF 0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-12#define maxn 1000100#define MOD 1000000007char s[100000];int col[100000], dp[21][1 << 20];int main(){ int n, m; scanf("%d %d", &n, &m); for (int i = 0; i < n; i++) { scanf(" %s", s); for (int j = 0; j < m; j++) col[j] |= (s[j] - '0') << i; } for (int i = 0; i < m; i++) dp[0][col[i]]++; for (int k = 1; k <= n; k++) for (int mask = 0; mask < (1 << n); mask++) { int sum = k > 1 ? (k - 2 - n) * dp[k - 2][mask] : 0; for (int p = 0; p < n; p++) sum += dp[k - 1][mask ^ (1 << p)]; dp[k][mask] = sum / k; } int ans = n * m; for (int mask = 0; mask < (1 << n); mask++) { int cnt = 0; for (int k = 0; k <= n; k++) cnt += min(k, n - k) * dp[k][mask]; ans = min(ans, cnt); } printf("%d\n", ans); return 0;}
- Codeforces Round #347 (Div. 1) E. Binary Table ★ ★ ★
- Codeforces Round #345 (Div. 2) E. Table Compression(并查集)★ ★
- Codeforces Round #170 (Div. 1) E.Binary Tree on Plane
- Codeforces Round #347 (Div. 1) E
- [Codeforces 277E][Round #170 div.1 E]Binary Tree on Plane
- Codeforces Round #345 (Div. 2) E. Table Compression
- Codeforces Round #390 (Div. 2)E Dasha and cyclic table
- Codeforces Round #170 (Div. 1) E. Binary Tree on Plane(费用流)
- [Codeforces Round #325][Div.1 E]
- Codeforces Round #323 (Div. 1) E
- Codeforces Round #200 Div.1 E tree
- Codeforces Round #343 (Div. 2) E. Famil Door and Roads (树形dp,lca)★ ★ ★
- Codeforces Round #359 (Div. 2)E. Optimal Point ★ ★ ★
- CodeForces Round #365 Div.2 E.Mishka and Divisors ★ ★ ★
- Codeforces Round #340 (Div. 2)E-XOR and Favorite Number(莫队算法)★ ★
- Codeforces Round #342 (Div. 2) E. Frog Fights set 模拟★ ★
- Codeforces Round #341 (Div. 2) E. Wet Shark and Blocks(矩阵优化DP)★
- 【Codeforces Round 367 (Div 2) E】Working routine 【十字链表 边框维护】 ★
- C++中模板的使用示例
- spark+java1.8+lamda wordCount 实例,并且实现按单词出现的次数的倒序排序
- POJ 2914 Minimum Cut 全局最小割
- Leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal 先序和中序中恢复二叉树 解题报告
- light oj 1212 - Double Ended Queue (双向队列)
- Codeforces Round #347 (Div. 1) E. Binary Table ★ ★ ★
- UVA10054The Necklace
- sed命令用法
- 写一个简单String类
- 第三周 项目一-顺序表的基本运算(1)
- 编译安装muduo库
- 设置label的描边
- 51Nod 1073 - 约瑟夫环(数论)
- 稀疏自动编码器 (Sparse Autoencoder)