CROC 2016 - Final Round [Private, For Onsite Finalists Only] C. Binary Table FWT
C. Binary Table
题目连接:
http://codeforces.com/problemset/problem/662/C
Description
You are given a table consisting of n rows and m columns. Each cell of the table contains either 0 or 1. In one move, you are allowed to pick any row or any column and invert all values, that is, replace 0 by 1 and vice versa.
What is the minimum number of cells with value 1 you can get after applying some number of operations?
Input
The first line of the input contains two integers n and m (1 ≤ n ≤ 20, 1 ≤ m ≤ 100 000) — the number of rows and the number of columns, respectively.
Then n lines follows with the descriptions of the rows. Each line has length m and contains only digits '0' and '1'.
Output
Output a single integer — the minimum possible number of ones you can get after applying some sequence of operations.
Sample Input
3 4
0110
1010
0111
Sample Output
2
Hint
题意
给你一个nm的01矩阵,然后每次操作:你可以挑选任意的某一行或者某一列翻转,然后你需要使得整个矩阵的1的数量尽可能少,问你最少数量是多少。
题解:
首先2^nm这个算法很简单:暴力枚举横着怎么翻转,然后每一列O(1)判断就好了。
然后正解怎么做呢?
我们令ans[i]是异或i之后的1的个数是多少,那么ans[i] = sigma(cnt[i]*num[i^j),cnt[i]表示列那个二进制为i的个数,num[i]表示二进制为i这个数的1的数量是多少。
这个很显然发现 i(ij) = i,这就是一个异或卷积的形式,用FWT加速计算就好了。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = (1<<20)+6;
int n,m,cnt[maxn];
long long x1[maxn],x2[maxn],ans[maxn];
string s[maxn];
long long t[maxn];
void utfxor(long long a[], int n) {
if(n == 1) return;
int x = n >> 1;
for(int i = 0; i < x; ++ i) {
t[i] = (a[i] + a[i + x]) >> 1;
t[i + x] = (a[i + x] - a[i]) >> 1;
}
memcpy(a, t, n * sizeof(long long));
utfxor(a, x); utfxor(a + x, x);
}
long long tmp[maxn];
void tfxor(long long a[], int n) {
if(n == 1) return;
int x = n >> 1;
tfxor(a, x); tfxor(a + x, x);
for(int i = 0; i < x; ++ i) {
tmp[i] = a[i] - a[i + x];
tmp[i + x] = a[i] + a[i + x];
}
memcpy(a, tmp, n * sizeof(long long));
}
void solve(long long a[],long long b[],int n)
{
tfxor(a,n);
tfxor(b,n);
for(int i=0;i<n;i++) a[i]=1LL*a[i]*b[i];
utfxor(a,n);
}
int main()
{
for(int i=0;i<maxn;i++){
int tmp = i;
while(tmp){
if(tmp&1)cnt[i]++;
tmp>>=1;
}
}
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
cin>>s[i];
for(int i=0;i<m;i++){
int tmp = 0;
for(int j=0;j<n;j++){
if(s[j][i]=='1')tmp+=1<<j;
}
x1[tmp]++;
}
for(int i=0;i<(1<<n);i++)
x2[i]=min(cnt[i],n-cnt[i]);
solve(x1,x2,1<<n);
long long ans = 1e15;
for(int i=0;i<(1<<n);i++)
ans=min(ans,x1[i]);
cout<<ans<<endl;
}
CROC 2016 - Final Round [Private, For Onsite Finalists Only] C. Binary Table FWT的更多相关文章
- CROC 2016 - Elimination Round (Rated Unofficial Edition) D. Robot Rapping Results Report 二分+拓扑排序
D. Robot Rapping Results Report 题目连接: http://www.codeforces.com/contest/655/problem/D Description Wh ...
- 8VC Venture Cup 2016 - Final Round (Div. 2 Edition)
暴力 A - Orchestra import java.io.*; import java.util.*; public class Main { public static void main(S ...
- CROC 2016 - Elimination Round (Rated Unofficial Edition) D. Robot Rapping Results Report 拓扑排序+二分
题目链接: http://www.codeforces.com/contest/655/problem/D 题意: 题目是要求前k个场次就能确定唯一的拓扑序,求满足条件的最小k. 题解: 二分k的取值 ...
- CF #CROC 2016 - Elimination Round D. Robot Rapping Results Report 二分+拓扑排序
题目链接:http://codeforces.com/contest/655/problem/D 大意是给若干对偏序,问最少需要前多少对关系,可以确定所有的大小关系. 解法是二分答案,利用拓扑排序看是 ...
- 8VC Venture Cup 2016 - Final Round (Div. 1 Edition) E - Preorder Test 树形dp
E - Preorder Test 思路:想到二分答案了之后就不难啦, 对于每个答案用树形dp取check, 如果二分的值是val, dp[ i ]表示 i 这棵子树答案不低于val的可以访问的 最多 ...
- CROC 2016 - Elimination Round (Rated Unofficial Edition) F - Cowslip Collections 数论 + 容斥
F - Cowslip Collections http://codeforces.com/blog/entry/43868 这个题解讲的很好... #include<bits/stdc++.h ...
- CROC 2016 - Elimination Round (Rated Unofficial Edition) E - Intellectual Inquiry dp
E - Intellectual Inquiry 思路:我自己YY了一个算本质不同子序列的方法, 发现和网上都不一样. 我们从每个点出发向其后面第一个a, b, c, d ...连一条边,那么总的不同 ...
- CROC 2016 - Elimination Round (Rated Unofficial Edition) E. Intellectual Inquiry 贪心 构造 dp
E. Intellectual Inquiry 题目连接: http://www.codeforces.com/contest/655/problem/E Description After gett ...
- CROC 2016 - Elimination Round (Rated Unofficial Edition) C. Enduring Exodus 二分
C. Enduring Exodus 题目连接: http://www.codeforces.com/contest/655/problem/C Description In an attempt t ...
随机推荐
- php使用位与运算符【&】或【|】实现权限管理
权限值是这样的2^0=1,相应2进数为”0001″(在这里^我表示成”次方”,即:2的0次方,下同)2^1=2,相应2进数为”0010″2^2=4,相应2进数为”0100″2^3=8,相应2进数为”1 ...
- JS实现滑动门效果
html部分 p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 31.0px Consolas; color: #2b7ec3 } p.p2 { margin ...
- 用C语言写的双色球
#include<stdio.h> #include<stdlib.h> #include<time.h> double jieguo(); void main() ...
- 非官方windows下Cpython二进制扩展包下载地址
Unofficial Windows Binaries for Python Extension Packages url:http://www.lfd.uci.edu/~gohlke/pythonl ...
- scrum 4.0
1.准备看板. 形式参考图4. 2.任务认领,并把认领人标注在看板上的任务标签上. 先由个人主动领任务,PM根据具体情况进行任务的平衡. 然后每个人都着手实现自己的任务. 3.为了团队合作愉快进展顺利 ...
- VMware12 安装 CentOS 6.5 64位
前言:本人在配置Hadoop的过程中,需要搭建Cent OS 64 环境,借此,顺便将Cent OS 64 的安装在此记录,方便自己,也方便大家学习.本次是在VM12虚拟机中实现Cent OS 64 ...
- Android横竖屏切换小结
Android横竖屏切换小结 (老样子,图片啥的详细文档,可以下载后观看 http://files.cnblogs.com/franksunny/635350788930000000.pdf) And ...
- linux tcp协议状态机
截图来自百度文库 TCP状态-有限状态机
- OWIN的理解和实践(一) – 解耦,协作和开放
概述 OWIN的全称是Open Web Interface For .Net, 是MS在VS2013期间引入的全新的概念, 网上已经有不少的关于它的信息, 这里我就谈下我自己的理解: OWIN是一种规 ...
- Dynamic CRM 2013学习笔记(二)插件基本用法及调试
插件是可与 Microsoft Dynamics CRM 2013 和 Microsoft Dynamics CRM Online 集成的自定义业务逻辑(代码),用于修改或增加平台的标准行为.也可 ...