4.1.7 Cutting Game(POJ 2311)
Problem description:
两个人在玩如下游戏。
准备一张分成 w*h 的格子的长方形纸张,两人轮流切割纸张。要沿着格子的边界切割,水平或者垂直地将纸张切成两部分。切割了n次之后就得到了n+1张纸,每次都选择切得的某一张纸再进行切割。首先切出只有一个格子的纸张(1*1的各自组成的纸张)的一方获胜。当双方都采取最优策略时,先手是必胜,还是必败?
2<=w,h<=200
Input:
w=2, h=2
Out put:
LOSE
前面的硬币问题2中,有n堆硬币,我们求出每堆硬币的Grundy值,再根据它们XOR后的值判断胜负。另一方面,这个游戏中,初始只有一张纸,纸张的数量随切割增加。这样会发生分割的游戏,也能够计算Grundy值(XOR运算满足结合律)。
当w*h的纸张分成两张时,假设所分得的纸张的Grundy值分别为g1和g2,则这两张纸对应的状态的Grundy值可以表示为g1 XOR g2。
在Nim中,不论有几堆石子,初始状态是怎么样的,只有XOR的结果相同,那么对胜负是没有影响的,这里也是同样的,只要Grundy值相同,即便发生切割,只要对分割后的各部分取XOR,就可以用这一个Grundy值来代表几个游戏复合而成的状态,Grundy值也可以同样计算。
了解了会发生分割的游戏的处理方法之后,只要像之前的问题一样,枚举所有一步能转移到的状态的Grundy值,就能够计算Grundy值了。
另外,切割纸张时,一旦切割出了长或宽为1 的纸张,下一步就一定能够切割出1*1的纸张,所以可以知道此时必败。因此,切割纸张时,总要保证长和宽至少为(无论如何都不能保证是,就是必败态。此时根据Grundy值的定义,不需要特别处理其Grundy值也是)。
const int MAX_WH =;
//记忆化搜索所用的数组,程序开始执行时全部初始化为-1
int mem[MAX_WH][MAX_WH];
int grundy(int w,int h){
if(mem[W][H]!=-) return mem[w][h];
set<int> s;
for(int i=;w-i>=;i++)
s.insert(grundy(i,h)^grundy(w-i,h));
for(int i=;h-i>=;i++)
s.insert(grundy(w,i)^grundy(w,h-i));
int res=;
while(s.count(res)) res++;
return mem[w][h]=res;
}
void solve(int w,int h){
if(grundy(w,h)!=) puts("WIN");
else puts("LOSE");
}
4.1.7 Cutting Game(POJ 2311)的更多相关文章
- Cutting Game(POJ 2311)
原题如下: Cutting Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5721 Accepted: 208 ...
- POJ 2311 Cutting Game(二维SG+Multi-Nim)
Cutting Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4798 Accepted: 1756 Desc ...
- POJ 2311 Cutting Game (Multi-Nim)
[题目链接] http://poj.org/problem?id=2311 [题目大意] 给出一张n*m的纸,每次可以在一张纸上面切一刀将其分为两半 谁先切出1*1的小纸片谁就赢了, [题解] 如果切 ...
- 【POJ 2311】 Cutting Game
[题目链接] http://poj.org/problem?id=2311 [算法] 博弈论——SG函数 [代码] #include <algorithm> #include <bi ...
- POJ 2311 Cutting Game(Nim博弈-sg函数/记忆化搜索)
Cutting Game 题意: 有一张被分成 w*h 的格子的长方形纸张,两人轮流沿着格子的边界水平或垂直切割,将纸张分割成两部分.切割了n次之后就得到了n+1张纸,每次都可以选择切得的某一张纸再进 ...
- POJ 2311 Cutting Game(SG函数)
Cutting Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4806 Accepted: 1760 Desc ...
- poj 2311 Cutting Game 博弈论
思路:求SG函数!! 代码如下: #include<iostream> #include<cstdio> #include<cmath> #include<c ...
- POJ 2311 Cutting Game(SG+记忆化)
题目链接 #include<iostream> #include<cstdio> #include<cstring> using namespace std; ][ ...
- POJ 2311 Cutting Game [Multi-SG?]
传送门 题意:n*m的纸片,一次切成两份,谁先切出1*1谁胜 Multi-SG? 不太一样啊 本题的要求是后继游戏中任意游戏获胜就可以了.... 这时候,如果游戏者发现某一单一游戏他必败他就不会再玩了 ...
随机推荐
- Visual Studio Code 的 launch.json 解析
{ "version": "0.2.0", "configurations": [ { "name": "(g ...
- 简单明了的掌握diff命令? 参考: http://www.ruanyifeng.com/blog/2012/08/how_to_read_diff.html
diff是比较两个 文本文件, 或目录,(中名字相同的文件) diff 是按行来比较的, 只要两个对应的行, 不完全一致, 就报告为不同, 否则就视为相同. (一行中任意一点的不同...) 检查时, ...
- 笔记本电脑切换到无线热点无法联网问题&Spring Cloud相关工程启动报错问题
通过禁用本地网络,和禁用另一个无线网络,以及禁用后重开,修改密码,重连的方式均失败后, 使用IE浏览器浏览提示失败,点击诊断,诊断出DNS服务器无响应异常. 突然想到通过ipconfig查看ip,网关 ...
- sudo用法记录
使用root用户,visudo命令(实际是编辑/etc/sudoers文件),用法和vim一样,末行模式:wq退出,如还有提示,使用大写"Q"保存退出,小写"e" ...
- 测试与CMMI质量体系
1. CMMI全称是Capability Maturity Model Integration,即能力成熟度模型集成(也有称为:软件能力成熟度集成模型) 其目的是帮助软件企业对软件工程过程进行管理和改 ...
- linux 进阶命令笔记(12月26日)
1. df 指令 作用:查看磁盘空间 用法: #df -h -h 表示以可读性较高的形式展示大小 2.free 指令 作用:查看内存使用情况 语法:#free -m -m表 ...
- memset()函数用法及其作用
memset()函数原型是: extern void *memset(void *buffer, int c, int count) //buffer:为指针或是数组, //c:是赋给buffer的值 ...
- hdu 3861 The King’s Problem trajan缩点+二分图匹配
The King’s Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- 【三十五】thinkphp之视图
1.模板定义 视图属于mvc中的v.一般是html结合php获取的数据提供给用户使用. 每个模板的文件都是独立的(文件名与控制器名称必须一样) 默认的模板文件规则是视图目录/[模板主题]控制器/操作名 ...
- android:ems="10"是什么意思
android:ems = " 设置TextView或者Edittext的宽度为10个字符的宽度.当设置该属性后,控件显示的长度就为10个字符的长度,超出的部分将不显示. xml中 andr ...