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)的更多相关文章

  1. Cutting Game(POJ 2311)

    原题如下: Cutting Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5721   Accepted: 208 ...

  2. POJ 2311 Cutting Game(二维SG+Multi-Nim)

    Cutting Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4798   Accepted: 1756 Desc ...

  3. POJ 2311 Cutting Game (Multi-Nim)

    [题目链接] http://poj.org/problem?id=2311 [题目大意] 给出一张n*m的纸,每次可以在一张纸上面切一刀将其分为两半 谁先切出1*1的小纸片谁就赢了, [题解] 如果切 ...

  4. 【POJ 2311】 Cutting Game

    [题目链接] http://poj.org/problem?id=2311 [算法] 博弈论——SG函数 [代码] #include <algorithm> #include <bi ...

  5. POJ 2311 Cutting Game(Nim博弈-sg函数/记忆化搜索)

    Cutting Game 题意: 有一张被分成 w*h 的格子的长方形纸张,两人轮流沿着格子的边界水平或垂直切割,将纸张分割成两部分.切割了n次之后就得到了n+1张纸,每次都可以选择切得的某一张纸再进 ...

  6. POJ 2311 Cutting Game(SG函数)

    Cutting Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4806   Accepted: 1760 Desc ...

  7. poj 2311 Cutting Game 博弈论

    思路:求SG函数!! 代码如下: #include<iostream> #include<cstdio> #include<cmath> #include<c ...

  8. POJ 2311 Cutting Game(SG+记忆化)

    题目链接 #include<iostream> #include<cstdio> #include<cstring> using namespace std; ][ ...

  9. POJ 2311 Cutting Game [Multi-SG?]

    传送门 题意:n*m的纸片,一次切成两份,谁先切出1*1谁胜 Multi-SG? 不太一样啊 本题的要求是后继游戏中任意游戏获胜就可以了.... 这时候,如果游戏者发现某一单一游戏他必败他就不会再玩了 ...

随机推荐

  1. Visual Studio Code 的 launch.json 解析

    { "version": "0.2.0", "configurations": [ { "name": "(g ...

  2. 简单明了的掌握diff命令? 参考: http://www.ruanyifeng.com/blog/2012/08/how_to_read_diff.html

    diff是比较两个 文本文件, 或目录,(中名字相同的文件) diff 是按行来比较的, 只要两个对应的行, 不完全一致, 就报告为不同, 否则就视为相同. (一行中任意一点的不同...) 检查时, ...

  3. 笔记本电脑切换到无线热点无法联网问题&Spring Cloud相关工程启动报错问题

    通过禁用本地网络,和禁用另一个无线网络,以及禁用后重开,修改密码,重连的方式均失败后, 使用IE浏览器浏览提示失败,点击诊断,诊断出DNS服务器无响应异常. 突然想到通过ipconfig查看ip,网关 ...

  4. sudo用法记录

    使用root用户,visudo命令(实际是编辑/etc/sudoers文件),用法和vim一样,末行模式:wq退出,如还有提示,使用大写"Q"保存退出,小写"e" ...

  5. 测试与CMMI质量体系

    1. CMMI全称是Capability Maturity Model Integration,即能力成熟度模型集成(也有称为:软件能力成熟度集成模型) 其目的是帮助软件企业对软件工程过程进行管理和改 ...

  6. linux 进阶命令笔记(12月26日)

    1. df 指令 作用:查看磁盘空间 用法: #df -h       -h 表示以可读性较高的形式展示大小   2.free 指令 作用:查看内存使用情况 语法:#free -m       -m表 ...

  7. memset()函数用法及其作用

    memset()函数原型是: extern void *memset(void *buffer, int c, int count) //buffer:为指针或是数组, //c:是赋给buffer的值 ...

  8. 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 ...

  9. 【三十五】thinkphp之视图

    1.模板定义 视图属于mvc中的v.一般是html结合php获取的数据提供给用户使用. 每个模板的文件都是独立的(文件名与控制器名称必须一样) 默认的模板文件规则是视图目录/[模板主题]控制器/操作名 ...

  10. android:ems="10"是什么意思

    android:ems = " 设置TextView或者Edittext的宽度为10个字符的宽度.当设置该属性后,控件显示的长度就为10个字符的长度,超出的部分将不显示. xml中 andr ...