博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF662C Binary Table
阅读量:5067 次
发布时间:2019-06-12

本文共 1217 字,大约阅读时间需要 4 分钟。

题目描述

有一个\(n\)\(m\)列的表格,每个元素都是\(0/1\),每次操作可以选择一行或一列,把\(0/1\)翻转,即把\(0\)换为\(1\),把\(1\)换为\(0\)。请问经过若干次操作后,表格中最少有多少个\(1\)

题解

但凡跟状态转移扯上一点关系的题目就没我什么事了……

首先,我们可以枚举每一行是否反转,然后每一次就可以\(O(m)\)的计算出答案,然而这样的复杂度是\(O(2^nm)\)的,会挂

我们设\(a[S]\)表示状态为\(S\)的列有多少个,\(b[S]\)表示状态\(S\)\(0\)\(1\)的个数中较小的那一个,设当前的行状态为\(now\),可以有如下转移\[ans=\sum_{i=0}^{2^n}a[i]\times b[i⊕now]\]

因为有\(i⊕i⊕now=now\),所以转移可以写成如下形式\[ans[now]=\sum_{i⊕j=now}a[j]*b[j]\]
\(FWT\)优化即可,复杂度为\(O(2^n\log(2^n))=O(n*2^n)\)

//minamoto#include
#define R register#define ll long long#define fp(i,a,b) for(R int i=a,I=b+1;i
I;--i)#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)template
inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}using namespace std;const int N=(1<<20)+5;char s[N];int sz[N],g[N],n,m,lim;ll A[N],B[N],ans=1e9;void FWT(ll *A,int ty){ for(R int mid=1;mid
<<=1) for(R int j=0;j
<<1)) for(R int k=0;k
>1]+(i&1); fp(i,0,lim-1)B[i]=min(sz[i],n-sz[i]); FWT(A,1),FWT(B,1);fp(i,0,lim-1)A[i]=A[i]*B[i]; FWT(A,-1);fp(i,0,lim-1)cmin(ans,A[i]); printf("%d\n",ans);return 0;}

转载于:https://www.cnblogs.com/bztMinamoto/p/10198577.html

你可能感兴趣的文章
一个自己写的判断2个相同对象的属性值差异的工具类
查看>>
oracle连接的三个配置文件(转)
查看>>
Python内置函数(29)——help
查看>>
oracle导出/导入 expdp/impdp
查看>>
Objective - C基础: 第四天 - 10.SEL类型的基本认识
查看>>
Android TextView加上阴影效果
查看>>
《梦断代码》读书笔记(三)
查看>>
Java8 Lambda表达应用 -- 单线程游戏server+异步数据库操作
查看>>
[Unity3D]Unity3D游戏开发MatchTarget的作用攀登效果实现
查看>>
AngularJS学习篇(一)
查看>>
关于Xshell无法连接centos6.4的问题
查看>>
css3动画——基本准则
查看>>
输入月份和日期,得出是今年第几天
查看>>
pig自定义UDF
查看>>
Kubernetes 运维学习笔记
查看>>
spring security 11种过滤器介绍
查看>>
代码实现导航栏分割线
查看>>
大数据学习系列(8)-- WordCount+Block+Split+Shuffle+Map+Reduce技术详解
查看>>
【AS3代码】播放FLV视频流的三步骤!
查看>>
枚举的使用
查看>>