uva11464(递推关系)

    xiaoxiao2021-03-25  100

    /* translation: 给出一个矩阵,每个数字要么0要么是1。可以将若干个0变换成1,问最少需要多少个这样的变换才能使得矩阵变成 偶数矩阵。一个偶数矩阵里面每一个数字的上下左右数字加起来的和都是偶数。 solution: 递推 关键是找到递推关系。因为一行最多只要15个数字,所以可以暴力枚举出第一行的状态。然后根据第一行的状态其实就可以确定下一行 的状态了。进而就可以推出整个矩阵的状态了。不断更新迭代,即可找到答案。 */ #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 15; const int INF = 0x3f3f3f3f; int grid[maxn + 5][maxn + 5], n; bool check(int s, int row) { for(int col = 0; col < n; col++) { if(grid[row][col] == 1 && !(s >> (n - 1 - col) & 1)) return false; } return true; } int count_bit(int s, int row) { int res = 0; for(int col = 0; col < n; col++) { if(grid[row][col] == 0 && s >> (n - 1 - col) & 1) res++; } return res; } int get_bit(int s, int p) { if(p < 0 || p >= n) return 0; if(s >> p & 1) return 1; else return 0; } int generate_next(int last_s, int s) { int next_s = 0; for(int i = 0; i < n; i++) { if((get_bit(s, i+1) + get_bit(s, i-1) + get_bit(last_s, i)) & 1) { next_s |= 1 << i; } } return next_s; } int calculate(int s, int last_s) { int res = 0; for(int i = 0; i < n; i++) { if(!check(s, i)) return INF; res += count_bit(s, i); int next_s = generate_next(last_s, s); last_s = s; s = next_s; } return res; } int main() { //freopen("in.txt", "r", stdin); int T, kase = 0; scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { scanf("%d", &grid[i][j]); } } int status = 0; for(int i = 0; i < n; i++) if(grid[0][n-i-1]) status |= 1 << i; int res = INF; for(int s = status; s < 1 << n; s++) { res = min(res, calculate(s, 0)); //printf("# = %d\n", calculate(s, 0)); } if(res >= INF) res = -1; printf("Case %d: %d\n", ++kase, res); } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-25062.html

    最新回复(0)