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. linux shell的for循环语法是怎样的?

    答:如下: ;i<100;i++)) do echo "i=${i}" done

  2. 更新32位Spyder从3.0.0-> 3.2.3

    https://stackoverflow.com/questions/51222550/how-to-update-spyder-3-3-0 It works!! 1. went to the An ...

  3. [转] Java 基础

    1. 面向对象和面向过程的区别 面向过程 面向对象 2. Java 语言有哪些特点 3. 关于 JVM JDK 和 JRE 最详细通俗的解答 JVM JDK 和 JRE 4. Oracle JDK 和 ...

  4. JavaScript(2)

    JavScript在页面上显示时间,首先我们先来了解关于时间的一些简单方法: getFullYear()  获取当前年份,getMonth() 0-n(一月到十二月),getDate() 1-31(月 ...

  5. JS相关重点知识 (概况)

    1.value和innerHTML没有联系,只是value是表单的一个特有属性,而innerHTML是通用的. 2.当从外部引入js文件时,该外部文件里面可以有多个方法,   html页面中的oncl ...

  6. JAVA关于泛型的笔记

    1.Java SE 5.0中增加泛型机制的主要原因是为了满足在1999年制定的最早的Java规范需求之一(JSR 14). 2.使用泛型机制编写的程序代码要比那些杂乱的使用Object变量,然后再进行 ...

  7. Error: Program type already present: com.google.gson.FieldAttributes 的解决方法

    在app中的build.gradle中加入如下代码, configurations { all*.exclude group: 'com.google.code.gson' all*.exclude ...

  8. JAVA 面向对象中的多态

    多态是继封装.继承之后,面向对象的第三大特性. 现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态. Java作为面向对象的语言,同样可以描述一个 ...

  9. Microsoft Active Directory(LDAP)连接常见错误代码

    接下来显示的认证错误类似于这样: "The exception is [ LDAP: error code 49 - 80090308: LdapErr: DSID-0Cxxxxxx, co ...

  10. DAY2 初识python

    一.编程语言介绍 1.1 机器语言:直接用计算机能理解的二进制指令编写程序,直接控制硬件 1.2 汇编语言:用英文标签取代二进制指令取编写程序,本质也是在直接控制硬件 1.3 高级语言:用人能理解的表 ...