博弈论——威佐夫博弈
2017-08-01 09:36
197 查看
威佐夫博弈(Wythoff Game):
有两堆各若干个石头,两个人轮流从某一堆或同时从两堆中取同样多的石头,规定每次至少取一个,多者不限,最后取光者得胜。
我们假设两堆石头的状态为 (a,b),表示第一堆剩下a个石子,第二堆剩下b个石子。当然这两堆是没有差别的,第一堆a个第二堆b个和第一堆b个第二堆a个是没有区别的。再假设两个人为A和B,A先取。
我们试想一下:如果A遇到两堆石头的状态为(0,0)是不是就代表着输了?我们称这种状态为奇异状态,也叫失败态。接下来的失败态为(1,2)、(3,5)、(4,7)、(6,10)、(8,13)……也就是说谁遇到这个状态谁就意味着失败。
为什么称这些状态为失败态呢??比如(1,2)这一状态,A如果遇到此状态,它有三种取法:
(1).取第一堆一个石子或第二堆两个石子,则状态变为(0,2)或(1,0),那么B直接取第二堆两个石子或第一堆一个石子,取完状态变为(0,0),则A输。
(2).取第二堆一个石子,则状态变为(1,1),那么B同时从两堆中取一个石子,取完状态变为(0,0),则A输。
(3).同时从两堆中取一个,则状态变为(0,1),那么B从第二堆取一个,取完状态变为(0,0),则A输。
所以A遇到(1,2),最后一定会转变为A遇到(0,0),同理其他奇异态都是如此。
我们用 a[i] 表示失败态中的第一堆的个数,用 b[i] 来表示失败态中的第二堆的个数,可以发现如下规律b[i]=a[i]+i(i从0开始),并且 a[i] 是前面的失败态中没有出现过的最小整数。
所有综上所述,失败态有三个基本的结论:
每个数字只存在一个失败态中
每个失败态都能转变为非失败态
每个非失败态也能转变为失败态
因为每个数都一定出现在一个失败态中,所以一个状态(a,b),要么a=a[i],要么b=b[i]。所以分以下两种情况进行讨论:
(1).当a=a[i]。
如果b==a时,则一次取完变为(0,0);如果b>b[i],那么从第二堆取走b−b[i]个石子,状态就变成了(a[i],b[i])。比如(3,7),从第二堆取走2个石子,就变成了(3,5);如果b<b[i],那么从两堆中同时取走 a−a[b−a[i]] 个石子就变成了 (a[b−a[i]],b−a[i]+a[b−a[i]])。比如(3,4),同时从两堆中取走2个石子就变成(1,2)。
(2).当b=b[i]。
如果 a>a[i],那么从第一堆取走 a−a[i]个石子,状态变为 (a[i],b[i]);如果 a<a[i],又分为两种情况:1).a==a[k](k<i),那么就从第二堆中取走 b−b[k]个石子,状态就变成了 (a[k],b[k]);2). a==b[k],这样只需从第二堆取走 b−a[k]个石子,状态就变成了(b[k],a[k]),然而两堆没有什么区别,所以等价于 (a[k],b[k])。
如何判断一个状态是否为失败态呢?知道这个我们就知道谁一定会输了,因为只要判断一个状态为失败态,先取的人一定会输。
用下面的公式进行判断:
a[i]=⌊i∗(1+5√)/2⌋; b[i]=a[i]+i;
代码如下:
有两堆各若干个石头,两个人轮流从某一堆或同时从两堆中取同样多的石头,规定每次至少取一个,多者不限,最后取光者得胜。
我们假设两堆石头的状态为 (a,b),表示第一堆剩下a个石子,第二堆剩下b个石子。当然这两堆是没有差别的,第一堆a个第二堆b个和第一堆b个第二堆a个是没有区别的。再假设两个人为A和B,A先取。
我们试想一下:如果A遇到两堆石头的状态为(0,0)是不是就代表着输了?我们称这种状态为奇异状态,也叫失败态。接下来的失败态为(1,2)、(3,5)、(4,7)、(6,10)、(8,13)……也就是说谁遇到这个状态谁就意味着失败。
为什么称这些状态为失败态呢??比如(1,2)这一状态,A如果遇到此状态,它有三种取法:
(1).取第一堆一个石子或第二堆两个石子,则状态变为(0,2)或(1,0),那么B直接取第二堆两个石子或第一堆一个石子,取完状态变为(0,0),则A输。
(2).取第二堆一个石子,则状态变为(1,1),那么B同时从两堆中取一个石子,取完状态变为(0,0),则A输。
(3).同时从两堆中取一个,则状态变为(0,1),那么B从第二堆取一个,取完状态变为(0,0),则A输。
所以A遇到(1,2),最后一定会转变为A遇到(0,0),同理其他奇异态都是如此。
我们用 a[i] 表示失败态中的第一堆的个数,用 b[i] 来表示失败态中的第二堆的个数,可以发现如下规律b[i]=a[i]+i(i从0开始),并且 a[i] 是前面的失败态中没有出现过的最小整数。
所有综上所述,失败态有三个基本的结论:
每个数字只存在一个失败态中
每个失败态都能转变为非失败态
每个非失败态也能转变为失败态
因为每个数都一定出现在一个失败态中,所以一个状态(a,b),要么a=a[i],要么b=b[i]。所以分以下两种情况进行讨论:
(1).当a=a[i]。
如果b==a时,则一次取完变为(0,0);如果b>b[i],那么从第二堆取走b−b[i]个石子,状态就变成了(a[i],b[i])。比如(3,7),从第二堆取走2个石子,就变成了(3,5);如果b<b[i],那么从两堆中同时取走 a−a[b−a[i]] 个石子就变成了 (a[b−a[i]],b−a[i]+a[b−a[i]])。比如(3,4),同时从两堆中取走2个石子就变成(1,2)。
(2).当b=b[i]。
如果 a>a[i],那么从第一堆取走 a−a[i]个石子,状态变为 (a[i],b[i]);如果 a<a[i],又分为两种情况:1).a==a[k](k<i),那么就从第二堆中取走 b−b[k]个石子,状态就变成了 (a[k],b[k]);2). a==b[k],这样只需从第二堆取走 b−a[k]个石子,状态就变成了(b[k],a[k]),然而两堆没有什么区别,所以等价于 (a[k],b[k])。
如何判断一个状态是否为失败态呢?知道这个我们就知道谁一定会输了,因为只要判断一个状态为失败态,先取的人一定会输。
用下面的公式进行判断:
a[i]=⌊i∗(1+5√)/2⌋; b[i]=a[i]+i;
代码如下:
#include<stdio.h> #include<cmath> #include<algorithm> using namespace std; int main() { int a,b; int k; while(scanf("%d%d", &a, &b)!=EOF) { if(a > b) swap(a, b); k = floor((b-a)*(1+sqrt(5.0))/2.0); if(k == a) printf("Lose\n");//为奇异状态 else printf("Win\n"); } return 0; }
相关文章推荐
- 博弈论(巴什博弈)(威佐夫博弈)(尼姆博奕)
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈) (转载)
- POJ.1067 取石子游戏 (博弈论 威佐夫博弈)
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈,sg函数)
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- 博弈论之威佐夫博弈(转载)
- 【博弈论】威佐夫博弈
- 博弈论模板(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- 博弈论模型(威佐夫博弈)
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- 博弈论(巴什博奕,威佐夫博弈,尼姆博弈,斐波那契博弈)
- 博弈论-巴什博弈-斐波拉契数-尼姆游戏-拍卖土地-威佐夫博弈入门理解Java
- 威佐夫博弈
- 博弈论之Nim博弈与sg函数(一)
- HDU.1846 Brave Game (博弈论 巴什博弈)
- bzoj 3298: [USACO 2011Open]cow checkers 威佐夫博弈
- hdu1527 威佐夫博弈
- poj 1067 取石子游戏(威佐夫博弈)