一開始,我發現有“必勝策略”,就知道是博弈論,然后看了兩種操作(月份+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;}
}