#SG函数,记忆化搜索#HDU 4111 Alice and Bob
题目
Alice和Bob两个好朋友又开始玩取石子了。
游戏开始时,有\(n\)堆石子排成一排,然后他们轮流操作(Alice先手),每次操作时从下面的规则中任选一个:
·从某堆石子中取走一个
·合并任意两堆石子
不能操作的人输。Alice想知道,她是否能有必胜策略。
分析
如果不存在大小为1的石堆,则操作次数一定被控制为\(sum+n-1\),判断奇偶性即可,
若存在大小为1的石堆,它有五种后继状态
- 直接取走大小为1的石堆
- 直接取走大小超过1的石堆中的一颗石子
- 将大小为1的石堆合并至大小超过1的石堆
- 合并两个大小超过1的石堆(不会影响操作次数)
- 将两个大小为1的石堆合并为1个石堆
根据5个后继状态SG函数值求出该状态的SG函数值即可
代码
#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
using namespace std;
int sg[51][60011],Test;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline signed min(int a,int b){return a<b?a:b;}
inline signed dfs(int one,int sum){
if (~sg[one][sum]) return sg[one][sum];
if (!one) return sg[one][sum]=sum&1;
if (sum==1) return sg[one][sum]=dfs(one+1,0);//全都是1
rr int MEX=dfs(one-1,sum);
if (sum) MEX=min(MEX,dfs(one,sum-1));
if (one>1) MEX=min(MEX,dfs(one-2,sum+2+(sum>0)));//合并两堆大小为1的石子
if (sum) MEX=min(MEX,dfs(one-1,sum+1));//将大小为1的石堆与大小超过1的石堆合并
return sg[one][sum]=MEX^1;
}
signed main(){
memset(sg,-1,sizeof(sg)),Test=iut();
for (rr int i=1;i<=Test;++i){
rr int one=0,sum=0;
for (rr int T=iut();T;--T){
rr int x=iut();
if (x==1) ++one;
else sum+=x+1;
}
sum-=(sum>0),dfs(one,sum);
printf("Case #%d: ",i);
puts(sg[one][sum]?"Alice":"Bob");
}
return 0;
}
#SG函数,记忆化搜索#HDU 4111 Alice and Bob的更多相关文章
- POJ 2311 Cutting Game(Nim博弈-sg函数/记忆化搜索)
Cutting Game 题意: 有一张被分成 w*h 的格子的长方形纸张,两人轮流沿着格子的边界水平或垂直切割,将纸张分割成两部分.切割了n次之后就得到了n+1张纸,每次都可以选择切得的某一张纸再进 ...
- hdu 4111 Alice and Bob 记忆化搜索 博弈论
Alice and Bob Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...
- 记忆化搜索 hdu 1331
Function Run Fun Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- hdu 4111 Alice and Bob(中档博弈题)
copy VS study 1.每堆部是1的时候,是3的倍数时输否则赢: 2.只有一堆2其他全是1的时候,1的堆数是3的倍数时输否则赢: 3.其他情况下,计算出总和+堆数-1,若为偶数,且1的堆数是偶 ...
- POJ2425 A Chess Game(SG函数+记忆化深搜)
题目链接:传送门 题目大意: 在一个有N个点的拓扑图上(拓扑图以邻接表的形式输入),放M个棋子(棋子与棋子之间无关,可以重合). 两人轮流移动棋子,每次只能移动一个棋子经过一条边. 问先手是否必胜. ...
- hdu 4111 Alice and Bob 博弈论
这里有2种方法: 方法一:求SG函数 sg[i][j]:i表示1的个数,j表示合并操作的步数. 这共有4种操作: 1.消除一个1: 2.减掉一个1: 3.合并2个1: 4.把1合并到另外不是1中. 代 ...
- HDU 4111 Alice and Bob (博弈+记忆化搜索)
题意:给定 n 堆石头,然后有两种操作,一种是把从任意一堆拿走一个,另一种是把一个石子放到另一堆上. 析:整体看,这个题真是不好做,dp[a][b] 表示有 a 堆1个石子,b个操作,操作是指把其他的 ...
- hdu 4111 Alice and Bob
组合游戏题: 组合游戏的规则: 1.必败态的所有后继都是必胜态: 2.必胜态最少有一个必败的后继: 这里的必胜态是f[1][0][0][0]; 其中f[a][b][c][d]表示有a个1,b个2,c个 ...
- BZOJ 3895 3895: 取石子 / Luogu SP9934 ALICE - Alice and Bob (博弈 记忆化搜索)
转自PoPoQQQ大佬博客 题目大意:给定n堆石子,两人轮流操作,每个人可以合并两堆石子或拿走一个石子,不能操作者输,问是否先手必胜 直接想很难搞,我们不妨来考虑一个特殊情况 假设每堆石子的数量都&g ...
- HDU 1176 免费馅饼(记忆化搜索)
免费馅饼 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
随机推荐
- Mybatis模糊查询无法确定参数$1的数据类型: ERROR: could not determine data type of parameter $1
Mybatis模糊查询无法确定参数$1的数据类型: 报错ERROR: could not determine data type of parameter $1 修改前: SELECT count(0 ...
- 【LeetCode字符串#04】左旋转字符串,以及反转函数使用说明
左旋转字符串 力扣题目链接(opens new window) 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部.请定义一个函数实现字符串左旋转操作的功能.比如,输入字符串"a ...
- JS笔记:方法两次调用,执行不同分支(公共变量,闭包,类三种方法实现)
好家伙, 当我们对一个方法进行两次调用,我们希望第一次执行A分支,第二次执行B分支,该怎么做? 这意味着在连续的两次调用中,方法的执行逻辑会交替执行不同的分支. 方法一:公共变量 let flag ...
- 数据结构(三):舞伴配对问题(C++,队列)
好家伙, 题目如下: 1.舞伴配对问题:假设在周末舞会上,男士们和女士们进入舞厅时,各自排成一队.跳舞开始时,依次从男队和女队的队头上各出一人配成舞伴. 2.若两队初始人数不相同,则较长的那一队中未配 ...
- 【Azure 应用服务】"App Service"如何能判断自身网路没有问题?
问题描述 当创建了一个App Service服务后,如何能判断服务自身网络链路路没有问题? 如果是用VM,通常用Ping可以判断.但是"网站应用App Service" 的Kudu ...
- electron-vite 可用,本机软件开发环境搭建
electron-vite 可用,本机软件开发环境搭建 https://electron-vite.github.io/
- vscode 快速重新启动 reload Window
vscode 快速重新启动 reload Window ctrl + shift + P 输入 reload
- config.js 多人同步更新 解决方案 多项目公用一套config.js dev
index.html <script type='text/javascript' src='<%= BASE_URL %>config.js?${Math.random().toS ...
- K8S容器环境下资源限制与jvm内存回收
一.k8s中的java资源限制与可能的问题 与以前单机跑单服务的情况相比,在k8s.docker容器化环境下的宿主机内存.cpu相对更大,所以当运行java类程序的时候,就必然有必要对容器进行内存限制 ...
- ubuntu切换root到user
目前知道: 从root用户切回user用户有三种方法: 1.su user (user是你自己安装时候的用户名) 2.直接输入exit 3.ctrl+D组合键