首页 > 代码库 > UVA 1557 - Calendar Game(博弈dp)
UVA 1557 - Calendar Game(博弈dp)
UVA 1557 - Calendar Game
题目链接
题意:给定一个日期,两个人轮流走,每次可以走一月或者一天,问最后谁能走到2001.11.4这个日子
思路:记忆化搜索,对于每个日期,如果下两个状态有一个非必胜态,那么这个状态是必胜态,如果后继状态都是必胜态,那么该状态为必败态
代码:
#include <stdio.h> #include <string.h> const int day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int dp[105][15][32]; int t, y, m, d; bool islead(int num) { num += 1900; if (num % 100 == 0) { if (num % 400 == 0) return true; } else { if (num % 4 == 0) return true; } return false; } bool judge(int y, int m, int d) { if (y >= 2001) { if (y > 2001) return false; if (m >= 11) { if (m > 11) return false; if (d > 4) return false; } } if (islead(y) && m == 2 && d == 29) return true; if (day[m] < d) return false; return true; } int dfs(int y, int m, int d) { if (dp[y][m][d] != -1) return dp[y][m][d]; if (y == 101 && m == 11 && d == 4) return dp[y][m][d] = 1; int dd = d, mm = m + 1, yy = y; if (mm > 12) { mm -= 12; yy++; } int ans = 1; if (judge(yy, mm, dd)) ans &= dfs(yy, mm, dd); int tmp = 0; if (islead(y) && m == 2) tmp = 1; dd = (d + 1); mm = m; yy = y; if (dd > day[m] + tmp) { dd -= day[m] + tmp; mm++; } if (mm > 12) { yy++; mm -= 12; } if (judge(yy, mm, dd)) ans &= dfs(yy, mm, dd); return dp[y][m][d] = (!ans); } int main() { memset(dp, -1, sizeof(dp)); scanf("%d", &t); while (t--) { scanf("%d%d%d", &y, &m, &d); y -= 1900; printf("%s\n", dfs(y, m, d)?"YES":"NO"); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。