http://codevs.cn/problem/3153/

对于这道题,直觉告诉我每一个状态一定是必胜或必败的

然后设定操作次数t,t为取完些石子最多需要多少步。

如果\(a_i\)不为1,\(t=\sum a_i+n-1\)。因为每次只让操作数减一。

但因为有\(a_i\)为1的情况,可以直接让操作数减二,所以我们把石子数为1的堆数和剩下的石子堆的操作数作为状态进行记忆化搜索。

正如xiaoyimi所说,细节确实很多QaQ

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 53;
const int M = 50003;
int in() {
int k = 0, fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = k * 10 + c - 48;
return k * fh;
} int n, a, cnt, sum;
bool vis[M][N], f[M][N]; bool pd(int tot, int num) {
if (vis[tot][num]) return f[tot][num];
vis[tot][num] = true;
if (tot == 1) return f[tot][num] = pd(0, num + 1);
if (num >= 1 && !pd(tot, num - 1)) return f[tot][num] = true;
if (num >= 2 && !pd(tot + 2 + (tot > 0), num - 2)) return f[tot][num] = true;
if (tot >= 2 && !pd(tot - 1, num)) return f[tot][num] = true;
if (num >= 1 && tot != 0 && !pd(tot + 1, num - 1)) return f[tot][num] = true;
return false;
} int main() {
int T; T = in();
while (T--) {
n = in(); sum = cnt = 0;
for(int i = 1; i <= n; ++i) {
a = in();
if (a == 1) ++cnt;
else sum += a + 1;
}
if (sum) --sum;
puts(pd(sum, cnt) ? "YES" : "NO");
}
return 0;
}

【CodeVS 3153】取石子游戏的更多相关文章

  1. Games:取石子游戏(POJ 1067)

    取石子游戏 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 37662   Accepted: 12594 Descripti ...

  2. HDU 2516 取石子游戏(斐波那契博弈)

    取石子游戏 Time Limit: 2000/1000 MS(Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...

  3. hdu 1527 取石子游戏(Wythoff Game)

    题意:Wythoff Game 思路:Wythoff Game #include<iostream> #include<stdio.h> #include<math.h& ...

  4. HDU 2516 取石子游戏(FIB博弈)

    取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  5. 1874: [BeiJing2009 WinterCamp]取石子游戏 - BZOJ

    Description小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问 ...

  6. HDU-1527 取石子游戏

    http://acm.hdu.edu.cn/showproblem.php?pid=1527 交换  :可实现. if( n < m ) { n^=m; m^=n; n^=m; } (三)尼姆博 ...

  7. bzoj 1874 取石子游戏 题解 &amp; SG函数初探

    [原题] 1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 334  Solved ...

  8. HDU 2516 取石子游戏 (博弈论)

    取石子游戏 Problem Description 1堆石子有n个,两人轮流取.先取者第1次能够取随意多个,但不能所有取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出" ...

  9. 【POJ】1067 取石子游戏(博弈论)

    Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...

  10. vijos 1557:bzoj:1413: [ZJOI2009]取石子游戏

    Description 在研究过Nim游戏及各种变种之后,Orez又发现了一种全新的取石子游戏,这个游戏是这样的: 有n堆石子,将这n堆石子摆成一排.游戏由两个人进行,两人轮流操作,每次操作者都可以从 ...

随机推荐

  1. js中的冒泡排序以及实现一个数组中得最到最大的数字小例

    这其实是一个很简单的js就可以实现,当然一般情况就是利用for循环,从第一个跟第二个开始比较,根据大小交互位置,思路很简单. 也就是js中的冒泡排序 冒泡排序 时间复杂度为O(n^2),有两个优点: ...

  2. android studio 应用小知识总结

    1.在复制一个工程文件后 想修改包名,则在Android下的java中的 Android test中,鼠标右键Refactor->rename->Rename_package->Do ...

  3. java内存设置

    在上边红色框内加入java内存设置命令: -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m

  4. [No00005A]word多文档合一

    2个方法:法一,一个个插入,法二,一次性插入多个. 法一: 视图->大纲视图 点击 大纲 -> 显示文档 点击插入,逐个插入文档.. 最终 将视图调回页面视图..结束. 法二: 插入 - ...

  5. javascript删除元素节点

    1.删除元素父节点 function removeElement(_element){ var _parentElement = _element.parentNode; if(_parentElem ...

  6. Java集合系列:-----------06List的总结(LinkedList,ArrayList等使用场景和性能分析)

    现在,我们再回头看看总结一下List.内容包括:第1部分 List概括第2部分 List使用场景第3部分 LinkedList和ArrayList性能差异分析第4部分 Vector和ArrayList ...

  7. Codevs 1051 二叉树最大宽度和高度

    1501 二叉树最大宽度和高度  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 白银 Silver       题目描述 Description 给出一个二叉树,输出它的最大宽 ...

  8. VS2013 抛出 stackoverflow exception 的追踪

    本公司使用VWG.Caslte ActiveRecord.CSLA.net .Quantz.net 等组件做为公司的开发基础,自2007年以来,一直工作正常,但最近(2015.12月)以来,打开MDA ...

  9. word里的代码格式,使之有底纹的效果

      实现效果: 怎么才能在word里实现这样的显示? 如何设置word里的代码格式,使之有底纹的效果

  10. nfs 三个参数权限

    遇到nfs客户端不可写的情况.  有延迟啊啊啊..  等1min左右就可以写了. 挂载参数: cat /var/lib/nfs/etab -->server cat /proc/mounts   ...