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
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 
#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<

 

你可能感兴趣的:(dp)