zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    世界企业家:创业者需知的8条创业逻辑
    比尔·盖茨的“机会”观——不追求机会,才会有机会
    我爱思佳(帮别人名字作诗)
    唐艺铭(帮别人名字作诗)
    我爱思佳(帮别人名字再作诗)
    优秀是一种习惯:智者五句话足以改变你的人生
    别了,我的情人
    李丽萍(帮别人名字作诗)
    Know GCS AND GES structure size in shared pool
    测试Exadata单个cell失败
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15367878.html
Copyright © 2011-2022 走看看