[GDKOI2016]染色大战
min-max对抗搜索回家再写
#include <iostream> #include <cstdio> #include <algorithm> #include <queue> using namespace std; inline int read() { int r=0;char c=getchar();bool f=0; while(!isdigit(c)){if(c=='-')f=1;c=getchar();} while(isdigit(c))r=(r<<3)+(r<<1)+(c^48),c=getchar(); return f?-r:r; } int n, m; int bin[25]; int mp[22][22], f[2][1<<22], e[22][22], val[22][22]; int END; int dfs(int x, int sit) { if (sit == END) return 0; if (f[x][sit]) return f[x][sit]; int res = -1e9; for (int i = 1 ; i <= n ; i ++) { for (int j = 1 ; j <= m ; j ++) { if (mp[i][j]) continue; int sum = 0; mp[i][j] = 1; if (mp[i][j] and mp[i-1][j] and mp[i][j-1] and mp[i-1][j-1]) sum += val[i-1][j-1]; if (mp[i][j] and mp[i-1][j] and mp[i-1][j+1] and mp[i][j+1]) sum += val[i-1][j]; if (mp[i][j] and mp[i+1][j] and mp[i+1][j+1] and mp[i][j+1]) sum += val[i][j]; if (mp[i][j] and mp[i+1][j] and mp[i][j-1] and mp[i+1][j-1]) sum += val[i][j-1]; if (sum) sum += dfs(x, sit + e[i][j]); else sum -= dfs(x^1, sit + e[i][j]); res = max(res, sum); mp[i][j] = 0; } } f[x][sit] = res; return res; } int main() { bin[0] = 1; for (int i = 1 ; i <= 21 ; i ++) bin[i] = bin[i-1] << 1; n = read(), m = read(); for (int i = 1 ; i <= n ; i ++) { for (int j = 1 ; j <= m ; j ++) { mp[i][j] = read(); e[i][j] = (1 << ((i - 1) * m + j - 1)); if (mp[i][j] == 0) END += e[i][j]; } } for (int i = 1 ; i <= n - 1 ; i ++) { for (int j = 1 ; j <= m - 1 ; j ++) { val[i][j] = read(); } } printf("%d\n", dfs(1, 0)); }