0
点赞
收藏
分享

微信扫一扫

[AcWing] 894. 拆分-Nim游戏(C++实现)博弈论SG函数例题

两岁时就很帅 2022-01-05 阅读 21

[AcWing] 894. 拆分-Nim游戏(C++实现)博弈论SG函数例题

1. 题目

在这里插入图片描述

2. 读题(需要重点注意的东西)

思路:
首先要知道几个定义

公平组合游戏(ICG)

必胜状态和必败状态

SG函数

mex运算

有向图游戏的和

SG值的意义

SG值的一个定理

本题思路:
在这里插入图片描述
本题的主要思路就是代结论,求出每个局面的SG值,但是需要注意,此题的局面有很多种,因为一堆石子(如上图a1)又可以分为两堆石子(如上图(b1,b2)、(c1,c2)),考虑所有的局面,用mex运算计算出sg值,然后代入结论:

3. 解法

---------------------------------------------------解法---------------------------------------------------

#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_set>

using namespace std;

const int N = 110;


int n;
int f[N];


int sg(int x)
{
    if (f[x] != -1) return f[x]; // 记忆化搜索

    unordered_set<int> S; // 用哈希表来存储
    
    // 当前状态可以变为如下局面
    for (int i = 0; i < x; i ++ )
        for (int j = 0; j <= i; j ++ )
            // 存储分出来的两堆石子sg值的异或
            S.insert(sg(i) ^ sg(j));

    for (int i = 0;; i ++ ) // mex运算求出该堆石子的sg值
        if (!S.count(i))
            return f[x] = i;
}


int main()
{
    cin >> n;

    memset(f, -1, sizeof f);

    int res = 0;
    while (n -- )
    {
        int x;
        cin >> x;
        res ^= sg(x); // 公式
    }

    if (res) puts("Yes");
    else puts("No");

    return 0;
}

可能存在的问题

4. 可能有帮助的前置习题

  • [AcWing] 893. 集合-Nim游戏(C++实现)博弈论SG函数模板题

5. 所用到的数据结构与算法思想

  • 博弈论
  • SG函数
  • 记忆化搜索

6. 总结

博弈论SG函数例题,理解思想并自己实现代码。

举报

相关推荐

0 条评论