Codeforces #663 (Div. 2) D. 505(状压dp)

A binary matrix is called good if every even length square sub-matrix has an odd number of ones.

Given a binary matrix aa consisting of nn rows and mm columns, determine the minimum number of cells you need to change to make it good, or report that there is no way to make it good at all.

All the terms above have their usual meanings — refer to the Notes section for their formal definitions.

Input

The first line of input contains two integers nn and mm (1≤n≤m≤1e6 and n⋅m≤1e6)  — the number of rows and columns in a, respectively.

The following nn lines each contain mm characters, each of which is one of 0 and 1. If the jj-th character on the ii-th line is 1, then ai,j=1. Similarly, if the jj-th character on the ii-th line is 0, then ai,j=0.

Output

Output the minimum number of cells you need to change to make aa good, or output −1 if it's not possible at all.

Examples

input

3 3
101
001
110

output

2

input

7 15
000100001010010
100111010110001
101101111100100
010000111111010
111010010100001
000011001111101
111111011010011

output

-1

Note

In the first case, changing a1,1 to 00 and a2,2 to 11 is enough.

You can verify that there is no way to make the matrix in the second case good.

Some definitions —

  • A binary matrix is one in which every element is either 1 or 0.
  • A sub-matrix is described by 4 parameters — r1, r2, c1, and c2; here, 1≤r1≤r2≤n and 1≤c1≤c2≤m.
  • This sub-matrix contains all elements ai,jai,j that satisfy both r1≤i≤r2r1≤i≤r2 and c1≤j≤c2c1≤j≤c2.
  • A sub-matrix is, further, called an even length square if r2−r1=c2−c1 and r2−r1+1 is divisible by 2.

思路:首先发现当n和m都大于3时,无解,因此在有解的情况中n必定小于4,我们可以考虑状压dp,枚举i和i-1列的合法状态。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
#define LL long long 
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,b,a) for(int i=b;i>=a;i--)
#define Mst(a,b) memset(a,b,sizeof(a))
#define fir first
#define se second
#define PII pair<int,int> 
#define lowbit(x) x&-x
const int N = 1e6+5;
int n,m;
int g[10][10],dp[N][10],s[N];
string str[N];
int get(int x,int y) {
    int cnt = 0;
    rep(i,0,2) {
        cnt += ((x>>i&1)^(y>>i&1));
    }
    return cnt;
}
bool check(int x,int y) {//判断是否合法
    if(m <= 1) return true;
    if(m <= 2) {
        int cnt = 0;
        rep(i,0,1) {
            cnt += (x>>i)&1;
            cnt += (y>>i)&1;
        }
        return cnt&1;
    }
    int cnt1 = 0,cnt2 = 0;
    rep(i,0,1) {
        cnt1 += (x>>i)&1;
        cnt1 += (y>>i)&1;
    }
    rep(i,1,2) {
        cnt2 += (x>>i)&1;
        cnt2 += (y>>i)&1;
    }
    return ((cnt1&1)&&(cnt2&1));
}
int main() {
	cin >> n >> m;
	rep(i,0,n-1) cin >> str[i];
	if(n == 1 || m == 1) {
	    cout << "0" << endl;
	    return 0;
	}
	if(n >= 4 && m >= 4) cout << "-1" << endl;
	else {
	    swap(n,m);
	    rep(i,0,n-1) {
	        int cnt = 0;
	        rep(j,0,m-1) {
	            cnt = cnt * 2 + (str[j][i] == '1');
	        }
	        s[i] = cnt;
	    }
		for(int i=0;i<1<<m;i++) {
		    for(int j=0;j<1<<m;j++) {
		        g[i][j] = get(i,j);
		        //cout << g[i][j] << ' ' << i << ' ' << j << endl;
		    }
		}
	    Mst(dp,0x3f);
	    for(int i=0;i<n;i++) {
	        for(int j=0;j<1<<m;j++) {
	            for(int k=0;k<1<<m;k++) {
	                if(check(j,k)) {
	                    dp[i][j] = min(dp[i][j],dp[i-1][k] + g[j][s[i]]);
	                }
	            }
	        }
	    }
	    int res = 1e9;
	    for(int i=0;i<1<<m;i++) res = min(res,dp[n-1][i]);
	    cout << res << endl;
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值