其他分享
首页 > 其他分享> > CF1592F Alice and Recoloring 题解

CF1592F Alice and Recoloring 题解

作者:互联网

Codeforces F1
Codeforces F2
Luogu F1
Luogu F2

Description.

有一个 01 矩阵,现在你有以下四种操作

  1. 选择一个包括 \((1,1)\) 的矩阵并对其反色
  2. 选择一个包括 \((n,1)\) 的矩阵并对其反色
  3. 选择一个包括 \((1,m)\) 的矩阵并对其反色
  4. 选择一个包括 \((n,m)\) 的矩阵并对其反色

每个操作的权值是给定的,其中

1 代价 2 代价 3 代价 4 代价
F1 1 2 4 3
F2 1 3 4 2

问全都消成 \(0\) 的最小代价。

Solution.

首先,发现不管是 F1 还是 F2 23 操作根本没用。
因为 23 总是可以通过 \(2\) 个 1 操作来完成。
肯定先贪心用 \(1\) 操作来覆盖。
这里相当于做个二阶差分。
考虑用 \(3\) 操作来替换 \(1\) 操作。
F1 的话就考虑如果有 \((n,m),(a,b),(a,m),(b,n)\) 就可以替换成 \(1\) 个 \((a,b)_3\)
可以使答案减小当且仅当 \((n,m),(a,b),(a,m),(b,n)\) 都是 \(1\)。
所以只需要替换一次。
F2 的话同理,\((n,m)\ne 1\) 时也可以替换使答案减小。
所以需要对其他都进行二分图匹配,先替换掉最多的 \(1\)。
然后再判断 \((n,m)\) 即可。

Coding.

点击查看 F1 代码
//是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
	x=0;char c=getchar(),f=0;
	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	f?x=-x:x;
}
template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
int n,m;char ch[505][505],fg[505][505];
int main()
{
	read(n,m);for(int i=1;i<=n;i++) scanf("%s",ch[i]+1);
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ch[i][j]=ch[i][j]=='B';
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) fg[i][j]=ch[i][j]^ch[i][j+1]^ch[i+1][j]^ch[i+1][j+1];
	int rs=0;for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) rs+=fg[i][j];
	if(fg[n][m]) for(int i=1;i<n;i++) for(int j=1;j<m;j++)
		if(fg[i][j]&&fg[i][m]&&fg[n][j]) return printf("%d\n",rs-1),0;
	return printf("%d\n",rs),0;
}
点击查看 F2 代码
//是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
	x=0;char c=getchar(),f=0;
	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	f?x=-x:x;
}
template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
int n,m,mt[505];char ch[505][505],fg[505][505],vs[505];
inline char dfs(int x)
{
	for(int y=1;y<m;y++) if(fg[x][y]&&fg[x][m]&&fg[n][y]&&!vs[y])
		{vs[y]=1;if(!mt[y]||dfs(mt[y])) return mt[y]=x,1;}
	return 0;
}
int main()
{
	read(n,m);for(int i=1;i<=n;i++) scanf("%s",ch[i]+1);
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ch[i][j]=ch[i][j]=='B';
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) fg[i][j]=ch[i][j]^ch[i][j+1]^ch[i+1][j]^ch[i+1][j+1];
	int rs=0;for(int i=1;i<n;i++) memset(vs,0,sizeof(vs)),dfs(i);
	for(int j=1,i;j<m;j++) if(mt[j]) i=mt[j],fg[i][j]^=1,fg[i][m]^=1,fg[n][j]^=1,fg[n][m]^=1,rs+=2;
	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) rs+=fg[i][j];
	int sm=rs-1;if(fg[n][m]) for(int i=1;i<n;i++) for(int j=1;j<m;j++)
		{int vl=sm-fg[i][j]-fg[i][m]-fg[n][j],tp=3-fg[i][j]-fg[i][m]-fg[n][j];rs=min(rs,tp+vl+2);}
	return printf("%d\n",rs),0;
}

标签:F1,F2,read,题解,char,int,CF1592F,505,Recoloring
来源: https://www.cnblogs.com/pealfrog/p/15367878.html