19日算法日记

算法引言

这几天是两场多校,导致图形学耽误了,考虑了一下在这之间就把算法的内容也塞进去(也是大佬的建议)。顺便也记录一下每天干了些甚么,到时候好找。根据自己的学习过程,也调整了一下顺序,有点帮助自然是喜不自矜。

两场多校还是补了不少知识点的,昨天把博弈补了一下,回顾了一下FFT,今天也来补笛卡尔树。

基础博弈(ICG公平组合博弈)

先来介绍基础博弈。

基础博弈大致有四种,算是必会内容,首先要确立的一点观念是:博弈游戏本质是找规律

当然这种说法非常武断,因为存在难以找到规律的博弈。但这么想有利于理解。

四种博弈分别为:Bash game(巴什博弈),Wythoff game(威佐夫博弈),Nimm game(尼姆博弈)与Fibonacci game(斐波那契博弈),这四种是四种非常特殊的博弈,一特殊在简单(相对于象棋等),二特殊在拥有必胜诀窍,并且这种诀窍可以在常数范围内进行概括。也就是常说的胜负在出生就决定了。

Bash game

    给一堆包含n个物品,二人分别从中取物,一次最多取m个,最少取1个,最后无法取走者败。

首先说结论:如$$n|(m+1)$$则先手必败,否则先手必胜。

暂停一下,思考一下为什么是n整除m+1时先手必败?

>

>

>

如果学过经济学的小伙伴听说过这样一个概念:盯紧的汇率政策。人民币在数年内都采取了这种保守的货币政策来对抗外界的恶意。这道题也是一样,他反应了博弈游戏种最关键的思想之一:不论对方做出什么样的决策,我都要并且能将其变为必胜的情况。

bash博弈是最简单的博弈,他就采取了盯紧的思想,也即,不论先手进行1-m的m种决策的任何一种,我都要令其变为m+1,来保证我的优势。这就是bash game的解题思路。

Wythoff game

有两堆各若干物品,两个人轮流从某一堆或两堆种取出等量的物品,每次至少取一个,多者不限,最后无法取走物品者败。

同样首先说结论:if(堆a<堆b),则满足a==int((b-a)*(sqrt(5)+1)/2关系的情况下后手必败。

>

>

>

在Bash game中我们获取了以不变应万变与盯紧的思想,而在Wythoff game中我们能学到什么呢?

注意到公式后方常数部分为黄金分割率,那末,也就是说ba之间有一个黄金分割率/常数的关联?这给了我们一个暗示,也即ab之间应有一个一次线性关系将我想要的解与数据相连。而谈到线性关系,就能想到二维图。如果大火悟性较强,这里应该早就看出sg矩阵的本质了,也就是画出一个二维图后遍历答案即可,也就是暴力sg法。

没有意识到的也不必灰心,幸运的是数学家们普遍悟性不高,我们从最基本的情况开始推断。

1.考虑这样一个点(0,0)也就是堆a为空,b也为空的情况。这种局面是必死的,也就是谁处在这个局面下,必输,这个点很关键,因为所有博弈问题都是根据这个点来的。

2.我们继续考虑(1,0)与(0,1),立刻的,我们发现,任何一个(0,n)与(n,0),都是后手必败,并且发现,ab的关系是关于y=x对称的。

3.再考虑没有0的情况(1,1),同样的,我们发现,任何一个(n,n)也都是后手必败。

4.那末ab不相等的情况呢?也即(1,2),我们将可能转移到(1,2)的情况全部列出:

(1,1)(1,0)(0,1),(0,2)

不必多言,聪明的带火立刻发现:这些全部是上面的情况,这是必死局面!并且通过我这样的表示,想必也意识到:Wythoff game是可以表示为二维数组的形式的。

完美,这些我们直接获得了sg矩阵的形成方法!立刻动手画图! ![来自](https://img-blog.csdnimg.cn/20210719232554607.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMTc5MDk5,size_16,color_FFFFFF,t_70#pic_center) 显然,我们观察到: 1、必死局面之间无法一次性转移到另一个必死局面 2、必活局面可以一次转移到一个必死局面 那末就不必多言,直接对函数上matlab拟合,我测试了几个点后得到的答案是1.622,这已经非常接近于1.618这个黄金分割率的值了,当然你可以尝试做出连续的证明,不过这不是计算机科学的研究范围了,兴许做图形学的那个我会很感兴趣(甩锅

Nimm博弈

    有三堆或以上的物品,两人轮流取走某堆任意多的物品,但只能取一堆,最后无法取走者败。

先说结论:每堆执行异或检测是否==0即可;

>

>

>

结论很简单,P2917五分钟做一下就会了。

难点在证明,我想了很久,找了一些资料,大概给出这样一个递推式与列举式的简单证明。如果大佬们知道严谨的证明请务必指导我,感恩!

假设结论正确,那末结论一定可以通过实践检验。

列出几种情况(0,0,0)(0,1,0)(1,1,0)(1,1,1)发现结论正确。

列举式的大致能得到正确的结论,但不严谨,根据概率学,如果一个方案能保证一定正确性,另一个方案也能保证一定的正确性,当他们一块执行的时候可以保证更高或不低的正确性。

因此我们还能考虑递推关系,也即如何从一个状态转移到必胜状态。

假设一k满足其为首位为1,其余为0的二进制数,我们可知这样一个k一定存在, 当k为异或结果的最高位1的值的时候。并且,这样的一个k一定能在堆的二进制表达中找到。这是由于异或的性质: ![真值表](https://img-blog.csdnimg.cn/20210719234722485.png) 显然,0^n=n,而如果结果有1,则必有一位在对应位置上存在1,否则无法出现1。

譬如9,6,5这样一组数,二进制化后为1001,110,101,异或后为:1010,则k为1000。

很简单吧,显然,这个k是一定能取到的,你只要每次将这个东西取走,就能将最终结果化为0的情况,接下来继续发挥我们从头用到尾的盯紧原则,对方只要破坏0的状态,我们就拿回去,恢复0的情况,而由于最终结果的异或一定为0,因此一定能得到结果。这是另一个思路,不甚严谨,是第一题的证明思路。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值