• 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;
    }
    
  • 相关阅读:
    CrashSight异常崩溃管理解决方案
    网址
    错误“Permission is not allowed”
    python连接虚拟机
    python对json文件的编码问题
    python取二次编码地图数据进行遍历修改再二次编码
    python对省份json的二次编码和二次解码
    H5调起支付宝支付
    人生~~~~
    部署服务的5中方式
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15367878.html
Copyright © 2020-2023  润新知