【POJ】【3537】Crosses and Crosses
博弈论
相当于放了x的位置,左右4格都不能再放x了,谁无处可放就输。
n<=2000
直接枚举后继状态,暴力求SG函数即可。
例: 0000000->x..0000 / .x..000 / ..x..00 / 0..x..0 / 00..x..
记忆化搜索写挂了……还是顺序DP靠谱= =(跟S-Nim类似的写法,暴力求SG函数)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 Source Code 2 Problem: 3537 User: sdfzyhy 3 Memory: 692K Time: 141MS 4 Language: G++ Result: Accepted 5 6 Source Code 7 8 //POJ 3537 9 #include<cmath> 10 #include<queue> 11 #include<vector> 12 #include<string> 13 #include<cstdio> 14 #include<cstring> 15 #include<cstdlib> 16 #include<iostream> 17 #include<algorithm> 18 #define rep(i,n) for(int i=0;i<n;++i) 19 #define F(i,j,n) for(int i=j;i<=n;++i) 20 #define D(i,j,n) for(int i=j;i>=n;--i) 21 using namespace std; 22 23 int getint(){ 24 int r=0,c=1; char ch=getchar(); 25 for(;!isdigit(ch);ch=getchar()) if (ch=='-') c=-1; 26 for(;isdigit(ch);ch=getchar()) r=r*10+ch-'0'; 27 return r*c; 28 } 29 const int N=2010,INF=~0u>>2; 30 const double eps=1e-9; 31 /******************template***********************/ 32 int dp[N],n; 33 bool vis[N],mark[N]; 34 35 int main(){ 36 n=getint(); 37 dp[0]=0; dp[1]=dp[2]=dp[3]=1; 38 F(i,4,n){ 39 memset(mark,0,sizeof mark); 40 mark[dp[i-3]]=mark[dp[i-4]]=mark[dp[i-5]]=1; 41 for(int j=1;j<=i-5-j;j++) 42 mark[dp[j]^dp[i-5-j]]=1; 43 F(j,0,n) if(!mark[j]){ dp[i]=j; break;} 44 } 45 printf("%d\n",dp[n] ? 1 : 2); 46 return 0; 47 }