Reprinted please indicate the source, thank youHttp://blog.csdn.net/acm_cxlove/article/details/7854526
By --- cxlove
Question: Give a matrix of N * n. Find an empty grid and place the two in turn into 0 and 1. Finally, we can see that there are more than 0 connections or more than 1 connections. (My statement is purely nonsense)
Http://poj.org/problem? Id = 3317
The question is whether the current person has an optimal strategy.
It is still a very small search, extracted from the empty lattice, because up to 10, you can compress the status.
As a result, the alpha-beta pruning of this question is useless. I tried it and the time was not reduced. Instead, you need to perform a memory-based search.
Compress the empty 3-digit lattice. Otherwise, it will use TLE.
Because it is the optimal policy for asking the current person, you can convert it to '0', which is a little more convenient.
However, alpha-beta pruning cannot be used in combination with memory-based search.
The following is taken from dicuss:
Alpha-beta pruning allows each sub-state to get a corresponding value under the constraints of its father and brother, so it is related to the parent node, the memory-based search function only has a relationship with the state of the child node by default, ignoring the constraints of the parent node. In fact, a game tree may have multiple nodes pointing to one node at the same time, if we combine alpha-Beta with memory, this node will be limited only once by a group of parent nodes, only the results of alpha-beta pruning brought by this group of fathers are taken into account. It is very likely that the optimal solution of the node belonging to another group of elders is cut out by mistake ......
I hope you can give me some advice.
# Include <iostream> # include <cstdio> # include <map> # include <cstring> # include <cmath> # include <vector> # include <queue> # include <algorithm> # include <set> # include <string> # define INF 1 <30 # define n 100005 # define maxn 100005 # define min (, b) (a) <(B )? (A) :( B) # define max (A, B) (a)> (B )? (A) :( B) # define Pb (a) push_back (a) # define MEM (a, B) memset (a, B, sizeof ()) # define EPS 1e-9 # define zero (a) FABS (a) <EPS # define ll long # define ull unsigned long # define lson (Step <1) # define rson (Step <1 | 1) # define mod 1000000007 # define MP (a, B) make_pair (a, B) using namespace STD; struct point {int X, y; point () {} Point (INT _ x, int _ y): X (_ x), y (_ y) {} p [10], ANSP; int N, TOT, best; char STR [10] [10 ]; Int vis [10] [10], TT; int way [4] [2] = {, 0,-, 0 }; int pw3 [15], DP [60000]; bool check (INT X1, int Y1, int X2, int Y2) {If (x1> = 0 & X2> = 0 & X1 <n & X2 <n & STR [X1] [Y1] = STR [X2] [Y2] &! Vis [X1] [Y1]) return true; return false;} void DFS (int I, Int J) {If (vis [I] [J]) return; TT ++; vis [I] [J] = 1; for (int K = 0; k <4; k ++) {int II = I + way [k] [0], JJ = J + way [k] [1]; If (check (II, JJ, I, j )) DFS (II, JJ) ;}} int get_score () {MEM (VIS, 0); int C1 = 0, C2 = 0; For (INT I = 0; I <n; I ++) for (Int J = 0; j <n; j ++) {TT = 0; if (vis [I] [J] = 0) DFS (I, j); If (STR [I] [J] = '0 ') c1 = max (C1, TT); else C2 = max (C2, TT);} return c1-c2;} int minsearch (INT, Int, Int, INT); int m Axsearch (INT, Int, Int, INT); int maxsearch (INT state, int DEP, int now, int alpha) {// The board is full, count the current situation. If (State = 0) return get_score (); If (DP [now]! =-INF) return DP [now]; int ans =-INF, St = State; // enumerate all positions while (ST) {int K = sT & (-St), Pos; For (Pos = 0; POS ++) if (1 <POS) & K) break; STR [p [POS]. x] [p [POS]. y] = '0'; int TMP = minsearch (State-K, DEP + 1, now + pw3 [POS], ANS); STR [p [POS]. x] [p [POS]. y] = '. '; ans = max (TMP, ANS); If (TMP> = alpha) return TMP; // update the optimal solution if (DEP = 0) {If (ANS> Best | (ANS = Best & (P [POS]. x <ANSP. X | (P [POS]. X = ANSP. X & P [POS]. Y <ANSP. y) {best = ans; ANSP = P [POS] ;}} St-= K;} r Eturn DP [now] = ans;} int minsearch (INT state, int DEP, int now, int beta) {// The board is full, count the current situation. If (State = 0) return get_score (); // perform a memory-based search. If (DP [now]! =-INF) return DP [now]; int ans = inf, St = State; // enumerate all positions while (ST) {int K = sT & (-St ), pos; // The number of points for (Pos = 0; POS ++) if (1 <POS) & K) break; // search STR [p [POS]. x] [p [POS]. y] = '1'; int TMP = maxsearch (State-K, DEP + 1, now + 2 * pw3 [POS], ANS); STR [p [POS]. x] [p [POS]. y] = '. '; ans = min (TMP, ANS); // pruning if (ANS <= beta) return ans; ST-= K;} return DP [now] = ans ;} int main () {pw3 [0] = 1; for (INT I = 1; I <= 10; I ++) pw3 [I] = pw3 [I-1] * 3; while (scanf ("% d", & N )! = EOF & N) {int C1 = 0, C2 = 0; Tot = 0; For (INT I = 0; I <n; I ++) {scanf ("% s", STR [I]); For (Int J = 0; j <n; j ++) {If (STR [I] [J] = '. ') P [tot ++] = point (I, j); else if (STR [I] [J] = '0') C1 ++; else C2 ++;} // we all set '0' as the first hand, so that if (C1> C2) {for (INT I = 0; I <N; I ++) for (Int J = 0; j <n; j ++) if (STR [I] [J] = '0 ') STR [I] [J] = '1'; else if (STR [I] [J] = '1 ') STR [I] [J] = '0';} Best =-INF; int ret; For (INT I = 0; I <pw3 [tot]; I ++) DP [I] =-INF; ret = maxsearch (1 <ToT)-1, 0, 0, INF); printf ("(% d, % d) % d \ n ", ANSP. x, ANSP. y, best);} return 0 ;}