目前在看贪心/构造/DP 杂题选做,发现一道非常不错的结论题,具有启发意义。

先说明如下结论

结论一:如何怎么样都不会使用二和三操作

证明:

二三操作显然可以通过两次一操作达到,而其操作费用大于两次一操作费用

所以显然我们只会操作一四操作。

那么我们发现翻转一整个矩形不好操作,翻转到一特定状态也不好处理,不如考虑倒序操作:即给定特定状态变为全白状态的费用,知其与原问题等价。

然后我们处理翻转问题,我们考虑一个转换

\(a_{i,j} = a_{i,j}\ xor\ a_{i+1,j}\ xor\ a_{i,j + 1}\ xor\ a_{i + 1,j + 1}\)。

我们发现全白时显然全等为\(0\)。

而一四操作我们可以将其本质变为:

一操作:单点翻转\((x,y)\)

四操作:四点翻转\((x,y),(x,m),(n,y),(n,m)\)

那么问题变得显然起来。

我们依旧给出了两个结论

结论二:不用同时使用两个横坐标或竖坐标相等的四操作

证明:其等价于修改四个任意散点,其可以等价于四次一操作的费用

结论三:除非 \((x,y),(n,y),(x,m)\) 都为1,才会使用 \((x,y)\) 这一四操作

证明:如果有一个不为\(1\),那么其有一个错误反转,我们需要其一个一操作反转回来,那么其等价于\(1 + 2 = 3\),可以使用一操作代替。

那么经典问题转化为满足某种条件的改变行列取点数量。

二分图上最大匹配即可。

#include<iostream>
#include<cstdio>
#include<queue>
#define ll long long
#define N 30000 int n,m; int head[N]; int cnt = 1; struct P{
int to,next;
ll v;
}e[N << 2]; inline void add(int x,int y,int v){
e[++cnt].to = y;
e[cnt].v = v;
e[cnt].next = head[x];
head[x] = cnt;
} std::queue<int>QWQ;
ll dis[N];
bool vis[N]; int a[505][505]; int s,t; inline bool bfs(){
for(int i = 1;i <= n + m + 2;++i)
dis[i] = 1e10,vis[i] = 0;
dis[s] = 0;
QWQ.push(s);
vis[s] = 1;
while(!QWQ.empty()){
int u = QWQ.front();
QWQ.pop();
vis[u] = 0;
for(int i = head[u];i;i = e[i].next){
int v = e[i].to;
if(dis[v] > dis[u] + 1 && e[i].v){
dis[v] = dis[u] + 1;
if(!vis[v])
vis[v] = 1,QWQ.push(v);
}
}
}
return dis[t] != 1e10;
} inline ll dfs(int u,ll in){
ll out = 0;
if(u == t)
return in;
for(int i = head[u];i;i = e[i].next){
int v = e[i].to;
if(e[i].v && dis[v] == dis[u] + 1){
int to = dfs(v,std::min(e[i].v,in));
e[i].v -= to;
e[i ^ 1].v += to;
in -= to;
out += to;
}
}
if(out == 0)
dis[u] = 0;
return out;
} inline int dinic(){
int ans = 0;
while(bfs())
ans += dfs(s,1e18);
return ans;
} int main(){
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j){
char s = getchar();
while(s != 'W' && s != 'B')
s = getchar();
a[i][j] = (s == 'B');
s = '.';
}
int ans = 0;
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j){
a[i][j] = a[i][j] ^ a[i + 1][j] ^ a[i + 1][j + 1] ^ a[i][j + 1];
}
// for(int i = 1;i <= n;++i,puts(""))
// for(int j = 1;j <= m;++j)
// std::cout<<a[i][j]<<" ";
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j){
if(a[i][m] && (a[n][j] && a[i][j])){
add(i,n + j,1);
add(n + j,i,0);
}
}
s = n + m + 1,t = n + m + 2;
for(int i = 1;i < n;++i)
add(s,i,1),add(i,s,0);
for(int j = 1;j < m;++j)
add(n + j,t,1),add(t,n + j,0);
int k = dinic();
a[n][m] = a[n][m] ^ (k & 1);
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j)
ans += a[i][j];
std::cout<<ans - k<<std::endl;
}//注意建图后的点集大小

CF1592F2 Alice and Recoloring 2的更多相关文章

  1. 贪心/构造/DP 杂题选做

    本博客将会收录一些贪心/构造的我认为较有价值的题目,这样可以有效的避免日后碰到 P7115 或者 P7915 这样的题就束手无策进而垫底的情况/dk 某些题目虽然跟贪心关系不大,但是在 CF 上有个 ...

  2. Solution -「构造」专练

    记录全思路过程和正解分析.全思路过程很 navie,不过很下饭不是嘛.会持续更新的(应该). 「CF1521E」Nastia and a Beautiful Matrix Thought. 要把所有数 ...

  3. (HDU 5558) 2015ACM/ICPC亚洲区合肥站---Alice's Classified Message(后缀数组)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5558 Problem Description Alice wants to send a classi ...

  4. 2016中国大学生程序设计竞赛 - 网络选拔赛 J. Alice and Bob

    Alice and Bob Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  5. bzoj4730: Alice和Bob又在玩游戏

    Description Alice和Bob在玩游戏.有n个节点,m条边(0<=m<=n-1),构成若干棵有根树,每棵树的根节点是该连通块内编号最 小的点.Alice和Bob轮流操作,每回合 ...

  6. Alice and Bob(2013年山东省第四届ACM大学生程序设计竞赛)

    Alice and Bob Time Limit: 1000ms   Memory limit: 65536K 题目描述 Alice and Bob like playing games very m ...

  7. 阿里前端框架Alice是个不错的选择

    BootStrap虽然用户群体广大,其整体风格尽管有不少skin可选,但以国情来看还是不好看. 阿里开源的前端框架,个人觉得还是很不错,Alice处处透着支付宝中界面风格的气息,电商感挺强. 以下内容 ...

  8. poj 1698 Alice‘s Chance

    poj 1698  Alice's Chance 题目地址: http://poj.org/problem?id=1698 题意: 演员Alice ,面对n场电影,每场电影拍摄持续w周,每周特定几天拍 ...

  9. Alice and Bob 要用到辗转相减

    Alice and BobTime Limit: 1 Sec  Memory Limit: 64 MBSubmit: 255  Solved: 43 Description Alice is a be ...

随机推荐

  1. 代码混淆保安全「GitHub 热点速览 v.21.43」

    作者:HelloGitHub-小鱼干 虽然让代码难以阅读看似是件难以理解的事情,但是混淆后的代码起到了类似加密的作用,而且经过混淆的代码依旧能实现原代码的功能.javascript-obfuscato ...

  2. django 中的hello word 开心,通过申请博客了,,发个随笔庆祝一下~~~~~~~

    django 中的hello word! 准备:[pymsql,pycharm,django3.0.7] >>>终端中:django-admin.py startproject [项 ...

  3. Redis:学习笔记-03

    Redis:学习笔记-03 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 7. Redis配置文件 启动 ...

  4. [对对子队]会议记录4.16(Scrum Meeting7)

    今天已完成的工作 何瑞 ​ 工作内容:完成成本和分数系统 ​ 相关issue:实现成本和分数系统的逻辑 ​ 相关签入:4.16签入1 吴昭邦 ​ 工作内容:对接流水线和成本和分数系统 ​ 相关issu ...

  5. [no code][scrum meeting] Beta 6

    $( "#cnblogs_post_body" ).catalog() 例会时间:5月19日11:30,主持者:黎正宇 下次例会时间:5月20日11:30,主持者:彭毛小民 一.工 ...

  6. java中延时队列的使用

    最近遇到这么一个需求,程序中有一个功能需要发送短信,当满足某些条件后,如果上一步的短信还没有发送出去,那么应该取消这个短信的发送.在翻阅java的api后,发现java中有一个延时队列可以解决这个问题 ...

  7. 零基础入门C/C++实现你的浪漫表白:浪漫流星雨表白程序

    想要讨女朋友欢心也巩固自己所学的知识,各位小伙伴有自己的想法了吗?准备好想要怎样实施了吗?有什么美好的计划了吗?如果没有的话那么别慌,我知道,在座的各位肯定都是有自己的心仪的姑娘,那么今天就教大家一招 ...

  8. linux中解压.tgz, .tar.gz ,zip ,gz, .tar文件

    转载:https://blog.csdn.net/fu6543210/article/details/7984578 将.tgz文件解压在当前目录: tar zxvf MY_NAME.tgz 将.ta ...

  9. hdu 5102 The K-th Distance (队列+生成法,,)

    题意: N个点的一棵树.定义点u和点v的距离等于它们之间的路径(唯一的)的长度.这样我们可以得到n*(n-1)/2个距离. 将它们从小到大排序,问前K个数的和是多少. 思路: 将边长为1的树枝都入队列 ...

  10. cf 24 Game (观察+.. 想一想)

    题意: 给一个数N,从1到N. 每次取两个数,三种操作:加.减.乘,运算完得一个数,把那俩数删了,把这个数加进去. 重复操作N-1次. 问是否可能得到24.若可以,输出每一步操作. 思路: 小于4,不 ...