Staircase-Nim博弈原理与证明

简介

Staircase-Nim博弈是Nim博弈的变形,它的定义是:

给定 \(n\) 堆物品,第 \(i\) 堆物品有 \(A_i\) 个,两人轮流取,每次可以从第 \(k\) 堆中取任意多个物品放到第 \(k-1\) 堆中,第 \(1\) 堆物品可以放到第 \(0\) 堆中,最后无法操作者失败

判断先手是否有必胜策略

推理

证明:先手必败当且仅当奇数堆的物品数异或和为 \(0\)

  • 所有物品都被移动到第 \(0\) 堆是一个必败局面,此时奇数堆物品异或和显然为 \(0\)

  • 若奇数堆异或和为 \(0\)

    • 若将偶数堆的物品移动到奇数堆,那么后手一定可以将这一步移动的物品再从奇数堆移动到下一个偶数堆,此时奇数堆异或和仍为 \(0\)
    • 若移动奇数堆的物品到偶数堆,那么等同于Nim博弈中的操作,奇数堆异或和一定不为 \(0\)
  • 若奇数堆异或和不为 \(0\) ,那么移动奇数堆物品,等同于Nim博弈中的操作,根据Nim博弈中的结论,一定存在操作使得奇数堆异或和变为 \(0\)

综上,由归纳法可知,命题成立

例题

POJ 1704

#include<cstdio>
#include<algorithm>
using namespace std;

const int MAX_N = 1000 + 5;
int p[MAX_N];

int main()
{
    int t, n, res;
    scanf("%d", &t);
    while(t--) {
        res = 0;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
            scanf("%d", &p[i]);
        sort(p + 1, p + n + 1);
        p[0] = 0;
        for(int i = n; i >= 1; i -= 2)
            res = res ^ (p[i] - p[i - 1] - 1);
        printf("%s will win\n", res ? "Georgia" : "Bob");
    }
    return 0;
}
posted @ 2022-02-20 11:33  f(k(t))  阅读(87)  评论(0编辑  收藏  举报