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;
    }
    
  • 相关阅读:
    ajax长轮询实现即时聊天室
    node.js 通过post上传图片并显示
    Java集合类详解
    多行子查询
    Oracle中查看用户下面所有表的语句
    关于Oracle的create
    Oracle数据库学习
    oracle数据库
    js 中 undefined、NaN、null
    学习数据库SQL语句2
  • 原文地址:https://www.cnblogs.com/Flash-plus/p/13834223.html
Copyright © 2011-2022 走看看