893. 集合-Nim游戏
SG函数
SG函数是解决博弈论问题的一把利器。
补充
1、\(Mex\)运算
设\(S\)表示一个自然数集合.定义\(Mex(S)\)为求出不属于集合\(S\)的最小自然数运算。 自然数是指非负整数,包括零。
例如:\(S=\{0,1,2,4\}\),那么\(Mex(S)=3\)。
2、\(SG\)函数
在有向图游戏中,对于每个节点\(x\),设从\(x\)出发共有\(k\)条有向边,分别到达节点\(y_1\),\(y_2\),····\(y_k\),
\(SG(x)=Mex(\{SG(y_1),SG(y_2)····SG(y_k)\})\)
整个有向图游戏\(G\)的\(SG\)函数值被定义为有向图游戏起点\(s\)的\(SG\)函数值,即 \(SG(G)=SG(s)\)。
终点的\(SG\)函数定义成\(0\)。
3、有向图游戏的和
设G1,G2,····,Gm是m个有向图游戏.定义有向图游戏G,他的行动规则是任选某个有向图游戏Gi,并在Gi上行动一步.G被称为有向图游戏G1,G2,·····,Gm的和.
有向图游戏的和的SG函数值等于它包含的各个子游戏SG函数的异或和,即:
SG(G)=SG(G1) ^ SG(G2) ^ ··· ^ SG(Gm)
4、延伸阅读
https://zhuanlan.zhihu.com/p/20611132
其中与本题有关的是第五节。简要来说,「异或」运算的发现,有这么两条线索:用一些 SG 数较小的状态作为例子,观察发现状态的组合对应着 SG 数的异或;提炼出状态组合的四条性质:交换律、结合律、归零律、恒等律,而异或运算也具有这四条性质。然而这些都只是「线索」,最终还是要用数学归纳法去证明状态的组合对应着 SG 数的异或。
C++ 代码
#include <bits/stdc++.h>
using namespace std;
// 理论参考
// https://www.cnblogs.com/greenpepper/p/11235232.html
const int N = 110, M = 10010;
int n, m;
int s[N]; //一共几种取法,比如一次取2个或5个。
int f[M]; //SG函数的值
//记忆化搜索来做,保证每个状态只被算一次
int sg(int x) {
//记忆化搜索
if (f[x] != -1) return f[x];
//它所有可以到的局面
unordered_set<int> S;
for (int i = 0; i < m; i++) {
int sum = s[i];
if (x >= sum) S.insert(sg(x - sum));//如果够取的话,那么就去取一下
}
//找出集合中不存在的这个自然数
for (int i = 0;; i++)
if (!S.count(i))
return f[x] = i;
}
int main() {
cin >> m; //一共几个允许的个数
for (int i = 0; i < m; i++) cin >> s[i]; //允许多少个拿取的数量,本题中是2和5
cin >> n;//一共几堆
//初始化数组值为-1
memset(f, -1, sizeof f);
int res = 0;
//n堆石子的SG函数,异或在一起,就像是基础NIM游戏一样,取得是否必胜还是必败
for (int i = 0; i < n; i++) {
int x;
cin >> x; //每堆里多少个
res ^= sg(x);
}
if (res) puts("Yes"); //必胜
else puts("No"); //必败
return 0;
}
原文地址:https://www.cnblogs.com/littlehb/p/15392613.html
- “高并发”问题如何解决?腾讯云一分钟配置的“黑科技”帮您
- 初探JavaScript(三)——JS带我"碰壁"带我飞
- 初探JavaScript(四)——作用域链和声明提前
- 开发人员看测试之运行Github中的JBehave项目
- 如何高效地合并Spark社区PR到自己维护的分支
- 开发人员看测试之TDD和BDD
- AngularJS入门心得1——directive和controller如何通信
- AngularJS入门心得2——何为双向数据绑定
- AngularJS入门心得3——HTML的左右手指令
- AngularJS入门心得4——漫谈指令scope
- Enterprise Library深入解析与灵活应用(8):WCF与Exception Handling AppBlock集成[上]
- 苹果就“电池门”公开致歉;微信下拉任务栏新增小游戏;美团打车进入北京
- 新华三《中国城市数字经济指数白皮书》:深圳数字经济发展水平国内居首
- NodeMCU模块写入MicroPython固件
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android So动态加载 优雅实现与原理分析
- 堆与栈区别
- 在Gaussian16中同时扫描两个反应坐标
- python调试神器traceback
- Centos安装高版本GCC
- Django+Vue开发生鲜电商平台之5.使用DRF实现商品列表页和过滤
- Spring 注入集合的成员变量属性
- 深入理解JVM(③)Java的锁优化
- 解Bug之路-Nginx 502 Bad Gateway
- bootstrap v4 toast轻提示正确用法
- 精华 | SQL注入万能Bypass技巧
- 【STM32F429开发板用户手册】第31章 STM32F429的SPI总线基础知识和HAL库API
- Linux 查找当前目录下所有包含指定内容的文件
- 父子管道更有效地扩展应用及其存储库结构
- Go语言 | 你还在这样获取文件的大小吗?