uva11464 Even Parity (枚举+递推)

先枚举出第一行的 (2^n) 种状态,然后递推出后面所有的行

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 20;
const int INF = 1000000007;

int T, n;

int a[maxn][maxn], b[maxn][maxn], c[maxn], ans;

void check(int s){
	int res = 0;
	for(int i = 1 ; i <= n ; ++i) for(int j = 1 ; j <= n ; ++j) b[i][j] = a[i][j];
		
	for(int i = 1 ; i <= n ; ++i){
		if((s >> (n - i)) & 1){
			if(a[1][i] == 0){
				++res;
				b[1][i] ^= 1;					
			} else{
				return;
			}
		}
	}
		
	for(int i = 2 ; i <= n ; ++i){
		for(int j = 1 ; j <= n ; ++j){
			int sum = 0;
			sum = b[i - 1][j - 1] + b[i - 1][j + 1] + b[i - 2][j];
			if((sum & 1) && !a[i][j]){
				b[i][j] ^= 1;
				++res;
			}
			if(!(sum & 1) && a[i][j]){
				return;
			}
		}
	}
		
	for(int i = 1 ; i <= n ; ++i){
		if((b[n][i - 1] + b[n][i + 1] + b[n - 1][i]) & 1) return;
	}
	
	ans = min(ans, res);
		
	return;
}

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
	T = read();
	for(int t = 1 ; t <= T ; ++t){
		memset(a, 0, sizeof(a));
		memset(b, 0, sizeof(b));
		memset(c, 0, sizeof(c));
		ans = INF;
		
		n = read();
		for(int i = 1 ; i <= n ; ++i) for(int j = 1 ; j <= n ; ++j) a[i][j] = read();
		
		for(int s = 0 ; s < (1 << n) ; ++s){
			check(s);
		}
		
		printf("Case %d: %d
", t, ans == INF? -1 : ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/tuchen/p/14838670.html