题意是黑板上有n个数\(S_i\)。每次操作可以把其中一个数减1或者将两个数合并为一个数。一个数变为0时,则不能再对其操作。

思路是发现最大的可操作次数为\( \sum S_i\)+(n - 1)。\( \sum S_i\)是把所有数消除需要的操作数。(n-1)表示我们最多可以合并(n-1)次。

同时我们发现,总操作数的奇偶决定了胜负。换言之,合并的次数决定论胜负。

当1个数为1时,假如我们将其消去,则合并的次数减1,总操作数的奇偶改变。

那么我们首先考虑,所有的数都>=2的情况,假如这种情况对应的最大的可操作次数为先手胜。那么因为所有数>=2,所以无论后手怎么操作,最多把某个数变为1。当后手把某个数变为1,先手将这个1与其他数合并,则不改变最大的可操作次数。

换言之,当每个数都>=2时,其最后的操作总数必然等于最大的可操作次数。也就是说,假如没有数是1,那么胜负则已经决定了。

所以我们对每个状态,只需要用1的个数和非1的数的个数,即可表示。

那么我们用one表示1的个数,m表示非1的数的总可操作数。

对于所有非1的数字,其变为1的情况只有m=1一种。

所以我们用dp(one,m)即可表示每个状态。然后扫其后续状态即可。具体的状态转移,看代码吧。

代码如下:

 #include"cstdio"
#include"iostream"
#include"cstring"
#include"algorithm"
#include"cstdlib"
#include"vector"
#include"set"
#include"map"
#include"cmath"
using namespace std;
typedef long long LL;
const LL MAXN=; int f[][];
int sg(int one,int m)
{
if(f[one][m]!=-) return f[one][m]; if(one==) return f[one][m]=((m%)==);
if(m==) return f[one][m]=sg(one+,); if(!sg(one-,m)) return f[one][m]=; // one中移出1个 if(m> && !sg(one,m-)) return f[one][m]=; // m操作1次 if(m> && !sg(one-,m+)) return f[one][m]=; // one中移动一个到m if(one>=) // 两个one合并
{
if(m> && !sg(one-,m+)) return f[one][m]=;
else if(m== && !sg(one-,m+)) return f[one][m]=;
} return f[one][m]=;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
memset(f,-,sizeof(f));
int t;
scanf("%d",&t);
for(int tt=;tt<=t;tt++)
{
int n,one=,m=;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int tmp;
scanf("%d",&tmp);
if(tmp==) one++;
else m+=(tmp+);
}
if(m) m--;
printf("Case #%d: ",tt);
if(sg(one,m)) printf("Alice\n");
else printf("Bob\n");
}
return ;
}

UVALive 5760 Alice and Bob的更多相关文章

  1. uvalive 5760 Alice and Bob (组合游戏,dp)

    题目链接: http://vjudge.net/problem/viewProblem.action?id=25636 对于>1的堆,必然会被其中一人全部合并. 然后就是二维dp,dp[非1堆的 ...

  2. UVaLive 5760 Alice and Bob (博弈 + 记忆化搜索)

    题意:有 n 堆石子,有两种操作,一种是从一堆中拿走一个,另一种是把两堆合并起来,Alice 先拿,谁不能拿了谁输,问谁胜. 析:某些堆石子数量为 1 是特殊,石子数量大于 1 个的都合并起来,再拿, ...

  3. 2016中国大学生程序设计竞赛 - 网络选拔赛 J. Alice and Bob

    Alice and Bob Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  4. bzoj4730: Alice和Bob又在玩游戏

    Description Alice和Bob在玩游戏.有n个节点,m条边(0<=m<=n-1),构成若干棵有根树,每棵树的根节点是该连通块内编号最 小的点.Alice和Bob轮流操作,每回合 ...

  5. Alice and Bob(2013年山东省第四届ACM大学生程序设计竞赛)

    Alice and Bob Time Limit: 1000ms   Memory limit: 65536K 题目描述 Alice and Bob like playing games very m ...

  6. sdutoj 2608 Alice and Bob

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2608 Alice and Bob Time L ...

  7. hdu 4268 Alice and Bob

    Alice and Bob Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Tota ...

  8. 2014 Super Training #6 A Alice and Bob --SG函数

    原题: ZOJ 3666 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3666 博弈问题. 题意:给你1~N个位置,N是最 ...

  9. ACdream 1112 Alice and Bob(素筛+博弈SG函数)

    Alice and Bob Time Limit:3000MS     Memory Limit:128000KB     64bit IO Format:%lld & %llu Submit ...

随机推荐

  1. BZOJ 1444 有趣的游戏(AC自动机+矩阵快速幂)

    真的是很有趣的游戏... 对每个单词构建好AC自动机后,由于单词都是相同长度的且不同,所以不会出现互相为子串的形式. 那么我们对AC自动机上的节点构建转移矩阵.对于每个单词末尾的节点.该节点的出边仅仅 ...

  2. scrollTop()案例

    设置 <div> 元素中滚动条的垂直偏移: 定义和用法 scrollTop() 方法返回或设置匹配元素的滚动条的垂直位置. scroll top offset 指的是滚动条相对于其顶部的偏 ...

  3. 怎样搭建一个自有域名的 WORDPRESS 博客?

    博客搭建并不复杂,只是过程有点繁琐,适合喜欢折腾的人,主要有下面几个步骤: 新建一个博客文件 购买域名(Domain Name) 注册一个主机空间(Web Host) 域名解析(DNSPod) 安装W ...

  4. P2323 [HNOI2006]公路修建问题

    题目描述 输入输出格式 输入格式: 在实际评测时,将只会有m-1行公路 输出格式: 输入输出样例 输入样例#1: 4 2 5 1 2 6 5 1 3 3 1 2 3 9 4 2 4 6 1 输出样例# ...

  5. 廖大大python学习笔记1

    列表classmates = ['Michael', 'Bob', 'Tracy']classmates.append('tom')print classmates# classmates.inser ...

  6. bzoj4010: [HNOI2015]菜肴制作(拓扑排序+贪心+堆)

    这题不是求最小字典序...撕烤了半个小时才发现不对劲T T 这题是能让小的尽量前就尽量前,无论字典序...比如1能在2前面就一定要在2前面... 显然是要先拓扑排序,让小的尽量前转化成让大的尽量往后丢 ...

  7. P1967 货车运输 树链剖分

    题目描述 AA国有nn座城市,编号从 11到nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最 ...

  8. Nginx基本功能极速入门

    http://xxgblog.com/2015/05/17/nginx-start/ 本文主要介绍一些Nginx的最基本功能以及简单配置,但不包括Nginx的安装部署以及实现原理.废话不多,直接开始. ...

  9. python学习(十三)进程和线程

    python多进程 from multiprocessing import Process import os def processFunc(name): print("child pro ...

  10. C语言 ------ #undef 的使用

    #undef 是在后面取消以前定义的宏定义 该指令的形式为 #undef 标识符 其中,标识符是一个宏名称.如果标识符当前没有被定义成一个宏名称,那么就会忽略该指令. 一旦定义预处理器标识符,它将保持 ...