博弈论讲解

简单博弈论https://blog.csdn.net/pengwill97/article/details/76796070#commentBox
sg函数讲解
https://www.cnblogs.com/DWVictor/p/10235851.html
NIM(尼姆)博弈
有三堆石子, 每堆有若干个,两个人轮流从某一堆中任取石子,每次至少取一个,多者不限,最后取完者获胜。
先手必败:A(XOR)B(XOR)C = 0。
否则先手必胜。可以推广到n堆。
巴什博弈
只有一堆n个石子,两个人轮流从这堆石子中取石子,规定每次至少取一个,最多取m个,最后取完的人获胜。
当 n % (m+1) = 0时,后手必胜。
当 n % (m+1) != 0时,先手必胜。
斐波那契博弈
有一堆个数为n的石子,游戏双方轮流取石子,满足:
先手不能再第一次把所有石子取完;之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间,包括1和对手取的石子数的2倍。取最后石子的人为赢家。
当且仅当n不是Fibonacci数时,先手必胜。换句话说,先手必败构成Fibonacci数列。
威佐夫博弈
有两堆各若干个石子,两个人轮流从某一堆或者两堆中取同样多的物品,规定每次至少取一个,多着不限,最后取完石子的人获胜。
先手必败的情况:对于一个奇异局势(A,B), A = 下取整[ (B-A) * 1.618 ],更准确的说,1.618 = (sqrt(5) + 1) / 2.
否则先手必胜,注意威佐夫博弈奇异局势的判定一定要用sqrt算出来,不能直接带1.618
sg函数模板
游戏和的SG函数等于各个游戏SG函数的异或和。
如果结果为0说明先手必败,否则先手必胜。
一定要把s数组开的大一点,至少比后继状态的数大。
一定要从小到大计算sg值

//f[N]:可改变当前状态的方式,N为方式的种类,f[N]要在getSG之前先预处理
//SG[]:0~n的SG函数值
//S[]:为x后继状态的集合
int f[n],sg[maxn],s[maxn];
void  getsg(int n)
{
    memset(sg,0,sizeof(sg));
    //因为SG[0]始终等于0,所以i从1开始
    for(int i = 1; i <= n; i++)
    {
        //每一次都要将上一状态 的 后继集合 重置
        memset(s,0,sizeof(s));
        for(int j = 0; f[j] <= i && j <= n; j++)
            s[sg[i-f[j]]] = 1;  //将后继状态的SG函数值进行标记 能够到达的状态
        for(int j = 0;; j++)
            if(!s[j])    //查询当前后继状态SG值中最小的非零值
            {
                sg[i] = j;
                break;
            }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值