目次

石取りゲーム(Nim)

石の山から交互に石を取っていくゲーム。三山崩し、などとも呼ばれる。

基本ルール

というゲームには、必勝法がある。

必勝法

最終状態(石が無くなった状態)は必勝形であり、自分が取った後に石が無くなる=自分が最後の石を取ったので勝ちである。
自分が取った後を必勝形にし続けると、いつかは最終状態、つまり最後の石を取れることになる。

証明

  1. 必勝形からどのように取ろうとも、必勝形のままにはできない
  2. 必勝形でない状態から、必勝形にする取り方が必ず1つ以上存在する
1の証明
2の証明

実際にできる方法を示す。

X で最も左に1が立っている桁を d 桁目とする。
        d
X    0001100101

d 桁目に1が立っている ai は必ず存在する(存在するからXでも立ってるのだ)
どれでもいいので1つ選ぶ

ai   1001001100

Xとaiのxorを計算する。これが操作後の ai' となるように、ai から石を取る

X^ai 1000101001
     ~~~|~~~~~~
      1 2   3

このとき、元の ai から、
1の範囲は変わらない
2の箇所(d桁目)は必ず 1→0 に変化する
3の範囲はいろいろ

変化する最も大きい桁が $d$ 桁目であり、それが1→0に減少しているので、操作後の $a_i'$ は必ず元の $a_i$ より小さい。

逆型ルール

必勝法

最初から石が1個の山しか無い場合、山の数 $N$ が奇数なら後手、偶数なら先手必勝となる。
石が2個以上の山が存在する場合を考える。

結論から言うと、逆型ルールでも必勝形を維持し続ける方が必勝である。

3の証明

NimK ルール

選べる山の数について、一般化されたNim。NimKと呼ばれるらしい。

必勝法

各山の石の個数を $A_i$ とし、$A_i$ を2進数表記する。bitごとに、全ての山について足し合わせる。

A1   1 0 1 1 0
A2   0 1 1 1 0
A3   1 0 0 1 0
--------------
     2 1 2 3 0

足し合わせた各桁について、$K+1$ で割った余りを取る。

これが全ての桁について $0$ なら後手必勝、$0$ でない桁があれば先手必勝。

つまり、

NimK の逆型ルール

必勝判定は変わらず。(最初から石が1個の山しかないなどのコーナーケースを除く)

途中までは通常と同じく、全ての桁のmod K+1 を0にしつつゲームを進める。

必勝側は、石が2個以上残る山の数が $K$ 個以下で渡された瞬間、「石が1個だけ残る山の個数を、$K+1$ で割ったときに1余るように残して取る」とよい。

Grundy数による一般化

このように、お互い交互に操作して状態を変化させ、それ以上操作できない状態になったら勝ちというゲームにおいて 先手・後手のどちらが必勝かは、Grundy数(ニム数、Nimber)というものを求めることで判定できる場合がある。

Grundy数が使えるのは、不偏ゲームに限られる。

Grundy数とは、以下によって求められる。

このGrundy数を各部分状態について求め、xorが0なら後手必勝、それ以外なら先手必勝となる。

石取りゲームに戻って当てはめると、

ちゃんと当てはまっている。

Grundy数の適用例

コンテスト過去問のネタバレ注意。

取れる石の上限が設定

例えば、「1つの山からは一度に3個までしか取れない」ルールが加わったとする。

すると石山のgrundy数は、

となる。要は4で割った余りだね。

部分状態を分割

「山から石を取るのでは無く、2つの山に分ける。全ての山を石1個にした方が勝ち」というルールになったとする。

状態が分裂して増えていくタイプも、分裂した各状態のxorで考える。
ある状態を状態 A,B,C に分割するような操作があったとして、遷移先のGrundy数は $G_A \hat{} G_B \hat{} G_C$ として扱えばよい(ただし、状態AのGrundy数を $G_A$ と表す)。

まぁ、蓋を開けてみればつまらないが、偶数なら1、奇数なら0となる。

取れる石の上限と下限が設定

競技プログラミングに出るようなNimの問題は、解けるようにできているので、 実際に実験をすると意外と単純な性質が見えることがある。

解法

山に残る石の数ごとに、取れる石の上限と下限が設定

やや高難度。
規則的な遷移にならないgrundy数は、遷移先全てのgrundy数を調べてそのMexを計算する必要があり、計算量がかさみやすい。

この問題では、計算量を現実的な程度に抑えるのに工夫が必要となる。

解法