zoukankan      html  css  js  c++  java
  • 题解 CF1391D

    比较哥哥。。。

    题意:

    给一个 (n imes m)(01) 矩阵,定义一个矩阵是好的当且仅当他每一个边长为偶数的子正方形矩阵都恰有奇数个 (1) ,问至少需要修改几个位置才能是的这个矩阵是好的(不可能输出-1)

    数据范围 :

    (n imes m geq 10^6)

    题解:

    首先,对于 (n geq 4) && (m geq 4) 的是肯定无解的

    证明如下:

    如果 (n geq 4) && (m geq 4)

    那么肯定存在 (4 imes 4) 的矩阵。

    那么这个 (4 imes 4) 应该要有奇数个 (1)

    但这个 (4 imes 4) 可以被分成 (4)(2 imes 2)

    每个 (2 imes 2) 要有奇数个 (1)

    (4) 个加起来就是偶数了。

    矛盾。

    再考虑其他情况。

    直接暴力 (dp) 一下就行了。

    因为必然有一个数小于 (3)

    所以复杂度最劣是 (O(10^6 / 3 * 8^2) = O(2e8 + 1e7))

    信仰一波就过了。。。

    至于如何 (dp) 还需要分类讨论。

    (n(m) == 1)(puts("0");) 就行了。

    (n(m) == 2)

    枚举 (0 o 3) 的所有情况。

    (dp[i][k] = min(dp[i][k], dp[i-1][j]) ^ (a[i]))

    (n(m) == 3)

    枚举 (0 o 7) 的所有情况。

    (dp[i][k] = min(dp[i][k], dp[i-1][j]) ^ (a[i]))

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #define maxn 1000010
    #define maxm 1000010
    #define ls x << 1
    #define rs x << 1 | 1
    #define inf 2000000000
    #define inc(i) (++ (i))
    #define dec(i) (-- (i))
    #define mid ((l + r) >> 1)
    #define int long long
    #define XRZ 1000000000
    #define debug() puts("XRZ TXDY");
    #define mem(i, x) memset(i, x, sizeof(i));
    #define Next(i, u) for(register int i = head[u]; i ; i = e[i].nxt)
    #define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout);
    #define Rep(i, a, b) for(register int i = (a) , i##Limit = (b) ; i <= i##Limit ; inc(i))
    #define Dep(i, a, b) for(register int i = (a) , i##Limit = (b) ; i >= i##Limit ; dec(i))
    int dx[10] = {1, -1, 0, 0};
    int dy[10] = {0, 0, 1, -1};
    using namespace std;
    inline int read() {
        register int x = 0, f = 1; register char c = getchar();
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
        return x * f;
    } int a[maxn], f[maxn][8], b[8]; char s;
    signed main() { int n = read(), m = read();
    	if(n >= 4 && m >= 4) { puts("-1"); goto QwQ;}
    	if(n >= m) Rep(i, 1, n) Rep(j, 1, m) scanf(" %c", &s), a[i] = (a[i] << 1) + s - '0';
    	else { Rep(i, 1, n) Rep(j, 1, m) scanf(" %c", &s), a[j] = (a[j] << 1) + s - '0'; swap(n, m);}
    	if(m == 1) { puts("0"); goto QwQ;} Rep(i, 1, 7) b[i] = b[i - (i & -i)] + 1;
    	if(m == 2) { Rep(i, 1, n) Rep(j, 0, 3) f[i][j] = inf; Rep(i, 0, 3) f[1][i] = b[i ^ a[1]]; int Ans = inf;
    		Rep(i, 2, n) Rep(j, 0, 3) Rep(k, 0, 3) if(b[j] + b[k] & 1) f[i][k] = min(f[i][k], f[i - 1][j] + b[k ^ a[i]]);
    		Rep(i, 0, 3) Ans = min(Ans, f[n][i]); if(Ans > XRZ) puts("-1"); else printf("%lld", Ans);
    	} else { Rep(i, 1, n) Rep(j, 0, 7) f[i][j] = inf; Rep(i, 0, 7) f[1][i] = b[i ^ a[1]]; int Ans = inf;
    		Rep(i, 2, n) Rep(j, 0, 7) Rep(k, 0, 7) if((b[j & 3] + b[k & 3] & 1) && (b[j >> 1] + b[k >> 1] & 1)) f[i][k] = min(f[i][k], f[i - 1][j] + b[k ^ a[i]]);
    		Rep(i, 0, 7) Ans = min(Ans, f[n][i]); if(Ans > XRZ) puts("-1"); else printf("%lld", Ans);
    	} QwQ:; return 0;
    }
    
  • 相关阅读:
    GoF23种设计模式之行为型模式之中介者模式
    GoF23种设计模式之行为型模式之备忘录模式
    GoF23种设计模式之行为型模式之解释器模式
    GoF23种设计模式之行为型模式之观察者模式
    GoF23种设计模式之行为型模式之状态模式
    GoF23种设计模式之行为型模式之策略模式
    GoF23种设计模式之行为型模式之模板方法
    GoF23种设计模式之行为型模式之访问者模式
    电子地图/卫星地图下载并转存为jpg图片
    webapi swagger学习笔记
  • 原文地址:https://www.cnblogs.com/Flash-plus/p/13834223.html
Copyright © 2011-2022 走看看