【2023.02.16】威佐夫博弈详解
威佐夫博弈详解
威佐夫博弈(Wythoff's game):有两堆各若干个物品,两个人轮流从任一堆取至少一个或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。——百度百科
威佐夫博弈,是博弈论的一道经典例题,题目大意是两个人在进行取子游戏,石子分为两堆,每堆有若干个石子,两个人按规则轮流取石子,先取完全部石子的人获胜。其中,规则如下:
- 每个人可以选择在同一堆石子中取任意个石子(可以全部取完),也可以在两堆石子中同时取相同个数的石子,但不可以不取。
那么,现在你作为先手,是否能够必胜呢(两人都具有绝对的智慧做出对自己最有利的选择)?
首先我们可以来分析一下这个问题中的奇异局势:
-
那么第一种想到必败的情况,肯定是(0,0)了。在(0,0)的情况中无论先手怎么走都不可能赢(
他压根走不了; -
第二种奇异局势的话通过计算可以得出是(1,2),当先手碰到(1,2)这种情况时,可以做出以下4种选择:
-
在第一堆石子中取一个石子,局面变为(0,2);
这时,后手只需将第二堆全部的石子都取走便可获得胜利。 -
在第二堆石子中取一个石子,局面变为(1,1);
这时,后手只需在两堆同时取走1个石子便可获得胜利。 -
在第二堆石子中取两个石子,局面变为(1,0):
这时,后手只需将第一堆全部的石子都取走便可获得胜利。 -
在两堆中同时取走一个石子,局面变为(0,1):
这时,后手只需将第二堆全部的石子都取走便可获得胜利。分析过后想必你也能看出来这是种必败的情况吧!
-
-
第三种奇异局势的话经过计算可以得出是(3,5),当先手碰到(3,5)这种情况时,可以做出以下11种选择:
-
在第一堆石子中取一个石子,局面变为(2,5):
这时,后手只需在第二堆石子中取四个石子,局面变为(2,1),上文已经推理过了,先手必败。 -
在第一堆石子中取两个石子,局面变为(1,5):
这时,后手只需在第二堆石子中取三个石子,局面变为(1,2),上文已经推理过了,先手必败。 -
在第一堆石子中取三个石子,局面变为(0,5):
这时,后手只需将第二堆全部的石子都取走便可获得胜利。 -
在第二堆石子中取一个石子,局面变为(3,4):
这时,后手只需在两堆中同时取两个石子,局面变为(1,2),上文已经推理过了,先手必败。 -
在第二堆石子中取两个石子,局面变为(3,3):
这时,后手只需在两堆中同时取三个石子,局面变为(0,0),先手必败。 -
在第二堆石子中取三个石子,局面变为(3,2):
这时,后手只需在两堆中同时取一个石子,局面变为(1,2),上文已经推理过了,先手必败。 -
在第二堆石子中取四个石子,局面变为(3,1):
这时,后手只需在第一堆中取一个石子,局面变为(2,1),上文已经推理过了,先手必败。 -
在第二堆石子中取五个石子,局面变为(3,0):
这时,后手只需将第一堆石子全部取走便可获得胜利。 -
在两堆石子中同时取走一个石子,局面变为(2,4):
这时,后手只需在第二堆石子中取走三个石子,局面变为(2,1),上文已经推理过了,先手必败。 -
在两堆石子中同时取走两个个石子,局面变为(1,3):
这时,后手只需在第二堆石子中取走一个石子,局面变为(1,2),上文已经推理过了,先手必败。 -
在两堆石子中同时取走三个石子,局面变为(0,2):
这时,后手只需将第二堆石子中的全部石子都取走,便可获得胜利。自然,你也可以看出(3,5)这种情况先手是必败的!
-
-
第三种奇异局势经过计算我们可以得出是(4,7),先手碰到这种情况可以做出以下15种情况:
-
在第一堆石子中取一个石子,局面变为(3,7):
这时,后手只需在第二堆石子中取两个石子,局面变为(3,5),上文已经推理过了,先手必败。 -
在第一堆石子中取两个石子,局面变为(2,7):
这时,后手只需在第二堆石子中取六个石子,局面变为(2,1),上文已经推理过了,先手必败。 -
在第一堆石子中取三个石子,局面变为(1,7):
这时,后手只需在第二堆石子中取五个石子,局面变为(1,2),上文已经推理过了,先手必败。 -
在第一堆石子中取四个石子,局面变为(0,7):
这时,后手只需将第二堆石子全部都取走便可获得胜利。 -
在第二堆石子中取一个石子,局面变为(4,6):
这时,后手只需在两堆中同时取一个石子,局面变为(3,5),上文已经推理过了,先手必败。 -
在第二堆石子中取两个石子,局面变为(4,5):
这时,后手只需在第一堆石子中取一个石子,局面变为(3,5),上文已经推理过了,先手必败。 -
在第二堆石子中取三个石子,局面变为(4,4):
这时,后手只需在两堆中同时取四个石子便可获得胜利。 -
在第二堆石子中取四个石子,局面变为(4,3):
这时,后手只需在两堆中同时取两个石子,局面变为(2,1),上文已经推理过了,先手必败。 -
在第二堆石子中取五个石子,局面变为(4,2):
这时,后手只需在第一堆石子中取三个石子,局面变为(1,2),上文已经推理过了,先手必败。 -
在第二堆石子中取六个石子,局面变为(4,1):
这时,后手只需在第一堆石子中取两个石子,局面变为(2,1),上文已经推理过了,先手必败。 -
在第二堆石子中取七个石子,局面变为(4,0):
这时,后手只需将第一堆石子全部都取走即可获得胜利。 -
在两堆石子中同时取走一个石子,局面变为(3,6):
这时,后手只需在第二堆石子中取走一个石子,局面变为(3,5),上文已经推理过了,先手必败。 -
在两堆石子中同时取走两个石子,局面变为(2,5):
这时,后手只需在第二堆石子中取走四个石子,局面变为(2,1),上文已经推理过了,先手必败。 -
在两堆石子中同时取走三个石子,局面变为(1,4):
这时,后手只需在第二堆石子中取走两个石子,局面变为(1,2),上文已经推理过了,先手必败。 -
在两堆石子中同时取走四个石子,局面变为(0,3):
这时,后手只需将第二堆石子全部都取走即可获得胜利。嗯,在我详细的讲解下,你已经明白了威佐夫博弈大概需要怎么做了吧!
-
接下来的奇异局势就是(6,10),(8,13)…… 那么,聪明的你一定发现了:
每个奇异局势两堆石子的差就是1,2,3,4,5……n!
再仔细计算,你还可以发现什么?
每一组奇异局势的较小数都是之前未出现的最小的数字!详细看一下:
-
第一组奇异局势之前出现过0,所以较小数为1;
-
第二组奇异局势之前出现过0,1,2,所以较小数为3;
-
第三组奇异局势之前出现过0,1,2,3,5,所以较小数为4;
……以此类推。
再看看,你发现了什么?
$ 1 \approx(2-1)* 1.618;$
$ 3 \approx(5-3)* 1.618;$
$ 4 \approx(7-4)* 1.618;$
……以此类推。
没错!就是第一个值 = 差值 * 1.618!
那么综合以上几点,就可以得出来公式了:
公式:
若设两堆石子数较小的为x,较大的为y,差值为z的话:
设 w = \((int)((\sqrt{5}-1)/2*z);\)
若 w = x,则这种情况先手必败;否则先手必胜。
例题:
洛谷 P2252 [SHOI2002]取石子游戏|【模板】威佐夫博弈
裸的板子题,直接放代码了:
Link
#include <bits/stdc++.h>
using namespace std;
int a;
int b;
int s;
int w;
inline int read(){
int s=0;
int w=1;
char ch;
ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-'){
w=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<1)+(s<<3)+(ch^48);
ch=getchar();
}
return s*w;
}
inline void write(int s){
if(s<0){
putchar('-');
s=~s+1;
}
if(s>9){
write(s/=10);
}
putchar(s+'0');
return ;
}
int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
a=read();
b=read();
s=abs(b-a);
w=(int)(s*((sqrt(5)+1)/2));
if(w==min(a,b)){
cout<<"0";
//fclose(stdin);
//fclose(stdout);
return 0;
}
else{
cout<<"1";
//fclose(stdin);
//fclose(stdout);
return 0;
}
//fclose(stdin);
//fclose(stdout);
return 0;
}
//Taunting_Wind
解释:
奇异局势:即先手必败的局势。
完结撒花!!!
By Taunting_Wind
本文来自博客园,作者:Hzzxx,转载请注明原文链接:https://www.cnblogs.com/xinao2186182144/p/Taunting_Wind.html