作者:wxyww

链接:https://ac.nowcoder.com/discuss/183993

来源:牛客网

SG函数

作用

对于一个状态i为先手必胜态当且仅当SG(i)!=0。

转移

那怎么得到SG函数尼。

SG(i)=mex(SG(j))(状态i可以通过一步转移到j)

首先说一下mex。一个集合的mex是最小的没有出现在这个集合里的非负整数。

其实想一下这个也是挺明显的。状态i是先手必败态当前仅当i转移到的状态都是先手必胜态。同样,只要当前状态可以转移到一个先手必败态,那么当前就是先手必胜态。

小定理

对于两个独立的游戏A,B,他们的SG函数=SG(A) ^ SG(B)

这个比较难描述,看一下后面的题就明白了。

真模板题

先来娱乐一下

题面

给一个有向无环图,一开始在某个节点有个棋子,Alice和Bob轮流操作,每次可以把石子移动一步。最后无法移动者失败。问是否存在先手必胜策略。

思路

SG函数的定义题。

出度为0的点的SG函数为1。每个点可以转移到的状态是可以走到的节点。直接在DAG上dp即可。

Nim游戏

博弈论入门必学。

Alice,Bob和一些石子的故事

level 1

传送门

有N堆石子。A B两个人轮流拿,A先拿。每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N及每堆石子的数量,问最后谁能赢得比赛。

例如:3堆石子,每堆1颗。A拿1颗,B拿1颗,此时还剩1堆,所以A可以拿到最后1颗石子。

输入

第1行:一个数N,表示有N堆石子。(1 <= N <= 1000)
第2 - N + 1行:N堆石子的数量。(1 <= A[i] <= 10^9)

输出

如果A获胜输出A,如果B获胜输出B。

输入样例

3
1
1
1

输出样例

A

--------------

分析

有n堆石子,第i堆石子有a[i]个,Alic和Bob轮流选择一堆从里面拿走任意多个石子(不能不拿),最后无法操作者失败,问是否存在先手必胜态。

思路

这就是上面那个小定理的应用了。考虑只有一堆石子的情况,肯定是先手必胜态。SG函数肯定是石子个数(显然)。

那么整个游戏的SG函数就是每个子游戏(只有一堆石子的情况)SG函数的异或之和。

所以这个题只要判断所有石子个数异或和是不是0即可。

level 2

有一堆共n个石子,Alice和Bob轮流从这堆石子里面取1到k个,不能取者输。问是否存在先手必胜策略

思路

状态i可以转移到的状态就是i-j(1<=j<=k)

所以SG(i)=mex(SG(i-j)) (1<=j<=k)

假设k=3

则SG(0)=0,SG(1)=1,SG(2)=2,SG(3)=3,SG(4)=0,SG(5)=1...

可以发现,到4的时候开始重新从0开始。仔细想一下就能发现为啥了。这就相当于拿个长度为k的窗口在这个序列里面滑动。新进来的数的SG函数就是刚好从窗口的出去的那个。

所以只要判断所以当前游戏的SG函数就是n%(k+1)

level 3

有一堆n个石子,Alice和Bob轮流这堆石子里面取石子,每次可以取l-r个,问是否存在先手必胜态。

思路

找规律!!

假设l=3,r=7

SG=[0,0,0,1,1,1,2,2,2,3,0,0.....]

发现SG(i)=i%(l + r) / l

dyh:sg函数的取值不容易直接思考,并且如果找到了规律 ⼀般都可以⽤数学归纳法证明。

level 4

有n堆石子,第i堆石子有a[i]个,Alice和Bob轮流操作,每次可以从一堆石子里面取任意多个,也可以把一堆石子分成两堆。不能操作者输。问是否存在先手必胜态。

思路

SG(i)=mex(SG(i - j),SG(i-j) ^ SG(j))

SG(i-j)是从石子里面取j个,SG(i-j)^SG(j)是将石子分成j和i-j两堆。

level 5

有1堆石子,Alice和Bob轮流操作,每次可以从一堆里面取当前个数的因数个(不能是本身),不能操作者(剩下一个)输。问是否存在先手必胜态。

思路

SG(i) = mex(SG(i-k)) (k|i)

找规律可以发现
SG(i) = __builtin_ctz(i)

也就是i的末尾0的个数

level 6

有1堆石子,Alice和Bob轮流操作,每次可以从一堆里面取与当前个数互质的数字个石子,不能操作者输,问是否存在先手必胜态

思路

SG(i)=mex(SG(i-j)) (gcd(i,j)=1)

打表如下

发现,对于偶数,SG为0.

对于奇数,SG为最小质因子的编号(就是最小质因子是第几个质数)

杂题

小题题

给定一个n*m的网格,第一行和第一列的元素标记着为胜或者为负,在某个位置有一个石子,Alice和Bob轮流操作,每次可以把这个石子往左或者往上移动一步。问是否存在先手必胜策略。

思路
先建个图,就成了一个DAG上的dp。找规律可以发现对角线上的SG函数都是相同的。

CF388C

有n排石子,每排有若干堆。Ciel可以选择一排,拿走这一排的第一堆石子。Jiro可以选择一排,拿走这一排的最后一堆石子。两个人都想要让自己的石子数量最多。问两个人最后的石子数量。Ciel先手。

思路

先考虑Ciel,他肯定可以保证自己至少得到每排石子的左半边。只要按照下面的原则做就可以:

第一个石子先随便选,如果Jiro和自己拿同一排,那就随便再选一个。
如果Jiro没和自己拿同一排,那就去和Ciel拿同一排。

考虑Jiro,同样可以保证自己至少得到每排石子的右半边。只要每次都和Ciel选同一排即可。

综上,就可以确定Ciel和Jiro分别拿了左半边和右半边。

对于奇数排的中间那一堆,从大到小从Ciel开始轮流选就行了。

/*
* @Author: wxyww
* @Date: 2019-03-06 19:55:16
* @Last Modified time: 2019-03-06 19:58:43
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<bitset>
#include<cstring>
#include<algorithm>
#include<string>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
const int N = 1000;
ll read() {ll x=0,f=1;char c=getchar();while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f;
}
ll ans1,ans2;
int m;
ll a[N];
bool cmp(int x,int y) {return x > y;
}
int main() {int n = read();for(int i = 1;i <= n;++i) {int k = read();int z = k >> 1;for(int j = 1;j <= z;++j) ans1 += read();if(k & 1) a[++m] = read();for(int j = 1;j <= z;++j) ans2 += read(); }sort(a + 1,a + m + 1,cmp);for(int i = 1;i <= m;++i) {if(i & 1) ans1 += a[i];else ans2 += a[i];}printf("%I64d %I64dn",ans1,ans2);return 0;
}

与作者交流:https://ac.nowcoder.com/discuss/183993

更多算法和题解:https://ac.nowcoder.com/acm/contest/discuss

中gcd函数_算法|博弈论入门(函数讲解+真题模板)相关推荐

  1. python中multiply函数_【python入门】multiply用法

    multiply(a,b)就是个乘法,如果a,b是两个数组,那么对应元素相乘 先来看个例子: 为什么上面的multiply(a, b)是这种结果,原因是multiply是ufunc函数 当我们使用uf ...

  2. matlab hist函数_算法工匠MATLAB专训营:Matlab绘图,小试牛刀

    作者 | 蔡老师 仿真秀专栏作者 首发 | 仿真秀平台 导读:正文之前,我在此详细说明一下,因为本文包含的程序太难得,网上肯定找不到这样的程序.随着讲课的越来越深入,我给出的程序会越来越实用,接近于实 ...

  3. python在工厂中的应用_什么是工厂函数?Python 中工厂函数怎么理解?

    其实谈工厂函数前必须首先把嵌套作用域和闭包讲清楚 python有一个很有意思的地方,就是def函数可以嵌套在另一个def函数之中.调用外层函数时,运行到的内层def语句仅仅是完成对内层函数的定义,而不 ...

  4. c++中STL的常用算法--1(函数对象,谓词,内建函数对象)

    函数对象 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象,也叫仿函数(functor),其实就是重载"()"操作符,使得 ...

  5. python偏函数和高阶函数_【Python入门】8.高阶函数之 匿名函数和偏函数

    目录 高阶函数 匿名函数 lambda 偏函数 高阶函数 匿名函数 lambda lambda,即希腊字母λ.顾名思义,匿名函数没有函数名,在运用时采取lambda x : ...的方式,如lambd ...

  6. inrange函数_掌握这些数学函数,你会在算法效率的分析时经常用到

    借助数学函数进行算法效率的对比分析 ▲ <程序员数学 从零开始>:如果没有必要的数学知识,几行简单的代码就会变成学习中的绊脚石 如何进行算法分析呢? 分别运行解决同一个问题的两个算法进行比 ...

  7. swap函数_[C++基础入门] 6、函数

    点击上方 蓝字 关注我呀! [C++基础入门] 6.函数 文章目录 6 函数 6.1 概述 6.2 函数的定义 6.3 函数的调用 6.4 值传递 6.5 函数的常见样式 6.6 函数的声明 6.7 ...

  8. excel中最常用的30个函数_最常用日期函数汇总excel函数大全收藏篇

    在我们的实际工作中,经常需要用到日期函数.日期函数那么多,你还只会用函数TODAY吗?那你就OUT了.今天一起来看下常用日期函数的用法! 1.DATE 函数DATE:返回在日期时间代码中代表日期的数字 ...

  9. mysql算法函数_十个实用MySQL函数

    本文首发于个人微信公众号<andyqian>,期待你的关注! 前言 继上一次<十个实用MySQL命令>后,今天奉上十个实用MySQL函数.下面都是一些比较常用且简单的函数,在工 ...

最新文章

  1. 10 个开源 Python OpenCV 小项目,YouTube热门
  2. win7 创建FTP站点
  3. windows下将iso文件挂载到文件夹
  4. ipython notebook 中 wavefile, display, Audio的使用
  5. 线上阿里云mysql慢_MySQL · 案例分析 · RDS MySQL线上实例insert慢常见原因分析-阿里云开发者社区...
  6. Daily Scrum 12/9/2015
  7. unixbench分析_unixbench测试CPU性能工具
  8. 小程序进入首页时弹出广告
  9. 使用Texmacs帮助您写格式规范统一的BLOG
  10. Java计算文件MD5值
  11. 在macOS上运行bitcoin客户端
  12. 关于ADC输入前级的抗混叠滤波器问题以及驱动负载电容的电阻值选择建议
  13. 【Java+MySQL】使用JDBC连接MySQL 8.0数据库
  14. excel转word_pdf转word软件永久jpg图片ppt转换excel编辑器压缩合并拆分去水印,加入自律圈即可获得!!!...
  15. 福利爬虫妹子图之获取种子url
  16. 代驾APP_第一章_项目环境搭建_第二节
  17. 电路中滤波电容和退耦电容_【硬见小百科】关于滤波电容、去耦电容、旁路电容作用及其原理...
  18. machinations游戏经济系统验证工具
  19. bash: cat/etc/group: 没有那个文件或目录
  20. matlab语音加入正弦噪声,基于Matlab的语音信号去噪声处理 毕业论文.doc

热门文章

  1. 如何在Windows Server 2016上配置iSCSI启动器
  2. Socket超时时间设置
  3. LNMP搭建论坛(php)
  4. 洛谷 P3396 哈希冲突 解题报告
  5. 【React Native 实战】微信登录
  6. LA 3989 - Ladies' Choice 稳定婚姻问题
  7. SpringBoot 实现热部署有哪几种方式
  8. 大数据学习路线2019版(附全套视频教程及网盘下载)
  9. 安装hive操作参考视频
  10. NOI.AC #31. MST