The main topic: given n heap of stones, two people take turns operation, each can merge two piles of stone or take a stone, not the author loses, ask whether the initiator win
It's hard to think straight, we might as well consider a special case.
Suppose the number of stones per heap is >1
Then we define operand B as the current total number of stones + current heap number-1
If B is odd, the initiator will win, otherwise the hand wins
Prove:
If there is only one pile at this moment, then correctness is obvious
Otherwise:
If B is an odd number, then the initiator needs only one synthesis operation, at which time the operand will be 1, and the heap with size 1 still does not exist.
Therefore only need to prove that B is even when the initiator must defeat
If the initiator chooses a composition operation, then the operand-1 does not have a heap of size 1, and the state returns to the state of the odd number of B.
If the initiator takes a pebble from a heap of a size >=3, the operand-1 and no heap of size 1, the state returns to the state of the odd number of B
If the initiator takes a pebble from a heap of 2 in size, then it needs to synthesize another stone with the other heap, the parity of B is constant and there is still no heap of size 1.
So B is even when the initiator will fail
Now back to the general situation there may be a heap of size 1
We have a heap with a size of 1, and the remainder of the heap is B
Then the current state can be represented by a two-tuple (a, B).
Easy to find a<=50,b<=50049
Then enumerate each action of the brute-force memory search
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1010using namespace Std;char f[60][50500];//1-initiator win 0-initiator will be defeated int N;char memorial_search (int a,int b) {if (a==0) return B& ; 1; If the heap of size 1 is not present, the winning or losing if (b==1) return Memorial_search (a+1,0) is calculated according to the operand. If the operand is 1 then only 1 stones in part B are zoned to a if (~f[a][b]) return f[a][b]; Char &re=f[a][b]; if (a &&!) Memorial_search (a-1,b)) return re=true; Take a stone in a heap of size 1 if (a && b &&!) Memorial_search (a-1,b+1)) return re=true; Merges a pebble in a heap of size 1 with a heap with a size not 1 if (a>=2 &&!) Memorial_search (a-2,b+2+ (b?1:0))) return re=true; Combine the two-size 1 heap in a stone if (b &&! Memorial_search (a,b-1)) return re=true; Merges or takes a stone from a heap of size >1 to make the operand-1 return re=false;} int main () {int t,i,x; Memset (f,-1,sizeof f); for (cin>>t; T t--) {cin>>n; int a=0,b=-1; for (i=1;i<=n;i++) {scanF ("%d", &x); if (x==1) ++a; else b+=x+1; } if (b==-1) b=0; Puts (Memorial_search (A, b)? " YES ":" NO "); } return 0;}
Bzoj 3895 Take the game Theory of stone + memory Search