博弈论入门

博弈论入门

博弈

巴什博弈 Bash Game

模型

只有一堆n个物品,两个人从轮流中取出(1~m)个;最后取光者胜。

思路

考虑到 若n=m+1 那么 第一个人不论如何取都不能取胜。

进一步我们发现 若 n=k*(m+1)+r; 先取者拿走 r 个,那么后者再拿(1~m)个

n=(k-1)*(m+1)+s; 先取者再拿走s 个 最后总能造成 剩下n=m+1 的局面。

因此,此时先手有必赢策略。相对应的,若n=k*(m+1) 那么先取者必输。

因此我们就可以写出对应程序(n,m>0)

int Bash_Game(int n,int m)//是否先手有必赢策略
{
    if (n%(m+1)!=0) return 1;
    return 0;
}

尼姆博弈 Nim Game

模型

当前有n堆每堆\(M_i>0\)个物品,两个人从轮流中取出若干个;最后取光者胜。

思路

从Bash Game中我们知道一个情形对应的一种状态,而从一个状态只能变成另一个状态时能很轻易的判定是否先手必胜

那么我们怎么把这样一个思想应用到Nim中呢

换句话说怎样才能在Nim中找到这样一个可以转化的状态

如果我们把n堆转化为n个整数,再将这n个整数用二进制表示,然后我们对这n个二进制数按位相加(不进位),若每一位相加都为偶数

那么我们称这个状态为偶状态,否则为奇状态;

可以证明:任何一个偶状态在其中一个数变小后一定会成为奇状态,一个奇状态一点可以通过改变一个数变为偶状态;

前一点很显然,因为一个数变小至少有一位发生变化,那么这一位就会改变原来的偶状态;

对于后一点,我们考虑一个从高位到低位某一位和为奇数的奇状态,必然有一个数的二进制此位为1,那么对于后面的较低位和为奇数的情况,只需要将这一位取反就可以得到一个偶状态;

那么现在我们就达到了成功的第一步——构造两个可以互相转化的状态并且显然存在奇状态为必胜态;偶状态为必败态;

那么我们对于n堆物品只需要判断他是否为奇状态就可以判定是否先手必胜;

但是对于每个数都二进制拆分非常麻烦,但是我们可以用神奇的位运算来完成这个过程

神奇的XOR与判断

如果有奇数个二进制数在第k为等于1那么显然在这一位上的和为奇数,同样的若有偶数个1则和为偶。

很明显位运算XOR满足我们的要求,偶数个1异或和为0,奇数个1异或和为1;

美滋滋这样不就搞完了

int Nimm_Game(int n)//假设n个数存在数组f[]中,有必胜策略返回1
{
    int flag=0;
    for(int i=1;i<=n;i++)
    flag^=f[i];
    if(flag) return 1;
    return 0;
}

一些小情况

但是当你遇到n非常大,并且每一堆的物品数是连续的整数的时候

我们就不能直接枚举n了

我们需要考虑连续非负整数的异或和问题

记\(f(x,y)\)为\(x\)到\(y\)的所有整数的异或和。

f[1,n]=f[0,n];

当存在\(n=2^k-1\)时\(,f(1,n)=f(0,n)=0,(k\geq2)\)

证明:

我们先来考虑\(f(2^k,2^{k+1}-1)\)

从\(2^k\)到\(2^{k+1}-1\)这\(2^k\)个数,最高位的一个数为\(2^k\);

若有\(k>=1\),则\(2^k\)为偶数,将这\(2^k\)个数的最高位去掉,异或和不变

因此\(f(2^k,2^{k+1}-1)=f(2^k-2^k,2^{k+1}-2^k-1)=f(0,2^{k}-1)\)

因而存在\(f(0,2^{k+1}-1)=f(0,2^k-1) xor f(2^k,2^{k+1}-1)=0\)

即\(f(0,2^k-1)=0\)

对于\(,f(0,n),n\geq4\)设n二进制表示的最高位1在第k位k>=2;

\(f(0,n)=f(0,2^k-1) xor f(2^k,n)=f(2^k,n)\)

对于\(2^k\)到\(n\)这\(n-2^k+1\)个数,最高位共有\(m=n-2^k+1\)个1,去除最高位的1

当n为奇数时,m为偶数此时有\(f(0,n)=f(2^k,n)=f(0,n-2^k)|2^k\)

由于\(n-2^k\)与n奇偶性相同,递推上面的公式可得\(f(0,n)=f(0,n-2^k-2^{k-1}-2^{k-2}\cdots -2^2)=f(0,n\%4)\)

当\(n\%4=1\)时\(f(0,n)=f(0,1)=1\)

当\(n\%4=3\)时\(f(0,n)=f(0,3)=0\)

当n为偶数时,m为奇数,因而\(f(0,n)=f(2^k,n)=f(0,n-2^k)xor2^k\)

也相当于最高位不变,递推公式可得

\(f(0,n)=f(0,n\%4)xor 2^kxor\) \(n[k]*2^k-1 xor\cdots\) \(n[2]*2^2\)

n[k]表示n的二进制表示的第k位

显然当n为偶数时 \(f(0,n)\)的二进制从最高位到第3位和n的二进制表示相同

此时我们只需要判断第二位

当\(n\%4=0\)时\(f(0,n)=n\)

当\(n\%4=2\)时\(f(0,n)=n+1\)

综上所述:

\[f(0,n)=f(1,n)\begin{cases}
n\ \ \ \ \ \ \ \quad n\%4=0\1\ \ \ \ \ \ \ \quad n\%4=1\\n+1 \quad n\%4=2\\0\ \ \ \ \ \ \ \quad n\%4=3\\end{cases}\]

代码给出来吧

//读入n,表示有从物品数分别1到n的n组物品,假设n个数存在数组f[]中
int xor_n(int n)//从1到n的异或和
{
     int t = n & 3;
     if (t & 1) return t / 2 ^ 1;
     return t / 2 ^ n;
}
int Nimm_Game(int n)//有必胜策略返回1
{
    int flag=0;
    for(int i=1;i<=n;i++)
    flag^=xor_n(f[i]);
    if(flag) return 1;
    return 0;
}

新Nim Game

在第一个回合中,第一个游戏者可以直接拿走若干个整堆的火柴。可以一堆都不拿,但不可以全部拿走。第二回合也一样,第二个游戏者也有这样一次机会。从第三个回合(又轮到第一个游戏者)开始,规则和Nim游戏一样。

如果你先拿,怎样才能保证获胜?如果可以获胜的话,还要让第一回合拿的火柴总数尽量小。

题解

我们第一次拿完后,要使得剩下的火柴中不存在异或和为0的子集,否则对方会将先手必败的状态留给我们。

所以我们可以使用贪心算法确定最优解。因此我们采用在线维护线性基的方法判断当前的数能否加入集合。


威佐夫博弈 Wythoff Game

模型

有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。

思路

原文地址:https://www.cnblogs.com/My-snowing/p/10439231.html

时间: 2024-10-04 17:45:16

博弈论入门的相关文章

博弈论入门题 kiki&#39;s game

Problem Description Recently kiki has nothing to do. While she is bored, an idea appears in his mind, she just playes the checkerboard game.The size of the chesserboard is n*m.First of all, a coin is placed in the top right corner(1,m). Each time one

POJ - 2348 Euclid&#39;s Game(博弈论入门题)

题目链接:poj.org/problem?id=2348 题意:给出两个数,两个人进行博弈,每个人都采取最优策略. 每个人可以进行操作:两个数中较大数减去较小数的倍数(可以是1,2...X倍),使得其中一个数先为零的获胜. 每次都先把较小值给a,较大值给b.一开始把必胜态给先手的那个人,然后进行判断. 1.b-a<=a  没办法只能一次一次计算,必胜态不断变换,直到其中一个数刚好为0. 2.b-a>a   不管怎样都是必胜态.b - xa <= a如果这个是必败态,那么b - (x-1)

博弈论入门小结

感受到了被博弈论支配的恐惧-- 入门的话个人按顺序推荐几篇论文: <由感性认识到理性认识--透析一类搏弈游戏的解答过程>张一飞 <解析一类组合游戏>  王晓珂 <组合游戏概述-浅谈SG游戏的若干拓展及变形> 贾志豪 看完这三篇还是要有点时间的,然而博主很傻的倒着看完了,然后就成功地完成了入门到放弃,事倍功半-- 到现在为止博弈论做了7道题,感觉只是大致学了一点皮毛,以后肯定回去再做一些题目,然而Hz书店没有和博弈论有关的书,差评. 只能说博弈论是一个很奇妙的东西,并没有

硬币游戏1(博弈论入门题)

题目链接:挑战程序设计竞赛p305 题意:一开始有X枚硬币,有K种取法,a[1],a[2]......a[k],取走最后一枚硬币为胜利者,两个人取硬币,都以最优策略取硬币,Alice先取,问最终谁是胜利者. 动态规划的思想(轮到Alice取硬币): 1.剩下0枚硬币,Alice为必败态. 2.剩下i枚硬币,存在一种情况 i - a[ j ] 为必败态,Alice为必胜态. 3.剩下i枚硬币,任何情况 i - a[ j ] 为必胜态,Alice为必败态. 1 void solve() 2 { 3

博弈论入门之斐波那契博弈

斐波那契博弈 斐波那契博弈是一种经典的博弈问题 有一堆石子,两个顶尖聪明的人玩游戏,先取者可以取走任意多个,但不能全取完,以后每人取的石子数不能超过上个人的两倍 结论 斐波那契博弈有一个非常重要的性质: 先手必败,当且仅当石子数为斐波那契数 是不是很神奇?? 证明: 懒得看了,这里有 代码 HDU 2516 #include<cstdio> #include<map> int fib[233],x; std::map<int,bool>mp; int main() {

随手练——博弈论入门 leetcode - 486. Predict the Winner

题目链接:https://leetcode.com/problems/predict-the-winner/ 1.暴力递归 当前数组左边界:i,右边界:j: 对于先发者来说,他能取到的最大值是:max(arr[i] + second(arr, i + 1, j), arr[j] + second(arr, i, j - 1)); (arr[i] + 作为后发者,在 i+1 到 j 上取得的值),(arr[j] + 作为后发者,在 i 到 j-1 上取得的值) 中大的一个. 对于后发者来说,他是被

【BZOJ】【1874】取石子游戏

SG函数 嗯博弈论入门题,关于SG函数这个东西可以去看VFK神犇的博客,讲的非常清楚Orz. 传送门:vfleaking.blog.163.com/blog/static/174807634201231792341827/    http://vfleaking.blog.163.com/blog/static/174807634201391304748444/ 然后这题直接暴力求SG函数就好了……反正数据规模也不大. 1 //BZOJ 1874 2 #include<cstdio> 3 #i

博弈论之入门小结

经过几天的学习和刷题,总算对博弈论的基础懂了一些,学习过程中参考了以下两位的总结: 博弈总结        博弈论题目列表 下面列出一些基础博弈的结论定理(证明过程略): (一)巴什博弈(Bash): 一个堆中有n个物体,两人轮流取,每次至少取1个,至多取m个,最后取完者胜. 取胜法则:令n=(m+1)*r+s  (s<=m,r为任意自然数),先取者要想取胜,则要求第一次取时必须取s个. (二)威佐夫博弈(Wythoff): 两个堆中各有若干个物品,两人轮流从某一堆或从两堆中同时取同样多个物品(

博弈论学习笔记(一)四个入门结论

题目一 情景一:在不被你对手看到的情况下,选择α或者β,我们会按以下方式给出你们的成绩:    如果你选择α而你对手选β,那么你得分+3而你的对手得分-1    如果你们都选α,那么你门的得分都+0    如果你选择β而你对手选α,那么你得分-1而你的对手得分+3    如果你们都选β,那么你们的得分都+1   α β α 0,0 +3,-1 β -1,3 +1,+1 这种情况下不管我的对手选择什么,我选α得到的结果总是最优的. 情景二:在不被你对手看到的情况下,选择α或者β,我们会按以下方式给