一开始,我发现有“必胜策略”,就知道是博弈论,然后看了两种操作(月份+1和天数+1),于是想到用记忆化搜索找出所有的可能性 ,但不知道怎么判断当前是否为先手必胜/必败态,使用了TJ方法后 ,才知道只要记录每个时间的状态,然后搜索即可
思路:
1. 记忆化搜索
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int mth[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int n,x,y,z,f[2010][15][35],vis[2010][15][35];
bool check(int x,int y,int z){if(x<2006) return true;if(x==2006&&y<11) return true;if(x==2006&&y==11&&z<4) return true;return false;
}//判断当前时间有没有超过2006.11.3
int dfs(int x,int y,int z){if((x%4!=0||x%100==0)&&x%400!=0&&y==2&&z==29) return 1;//判断当年非闰年2月有29日的问题if(z>mth[y]) z=1,y++;if(y>12) x++,y=1; //上面两行位置不能交换,必须从日期到月份if(vis[x][y][z]) return f[x][y][z];vis[x][y][z]=1;if(z<=mth[y+1]&&check(x,y+1,z)){f[x][y][z]=(dfs(x,y+1,z)^1);} if(check(x,y,z+1)){f[x][y][z]|=(dfs(x,y,z+1)^1);}//下一次操作为必败,则当前必胜,因此^1return f[x][y][z];}
int main(){f[2006][11][3]=1;dfs(1900,1,1); //初始化cin>>n;for(int i=1;i<=n;i++){cin>>x>>y>>z;if(f[x][y][z]) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
}