三种基本博弈结论

1.巴什博奕:

1、  本游戏是一个二人游戏;
2、  有一堆石子一共有n个;
3、  两人轮流进行取石子;
4、  每走一步可以取走1到m个石子(至少1个,最多m个);
5、  最先取光石子的一方为胜。

当n=m+1时,无论怎么取,先手都是必败。

所以当n=p*(m+1)时,无论先手取几个,对手取的个数只要和自己取的个数加起来等于m+1,先手就会必败,此时为先手必败态。

当n=p*(m+1)+q时先手只要取走q个,对手就会陷入必败态,此时先手必胜。

例题:http://acm.hdu.edu.cn/showproblem.php?pid=1846

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
const ll mod=1e9+7;
ll t,n,m;
int main()
{
    cin>>t;
    while(t--)
    {
        int f=0;
        cin>>n>>m;
        if(n%(m+1)==0)f=0;
        else f=1;

        if(f)cout<<"first"<<endl;
        else cout<<"second"<<endl;
        
    }
}

2.威佐夫博奕:

有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者

用(a[k],b[k])(a[k] ≤ b[k] ,k=0,1,2,...,n)( a[k] 其中 k 为下标 )表示两堆物品的数量并称其为局势。

如果面对(0,0),此时做选择的人已经输了,这种局势定义为奇异局势。

前几个奇异局势:

(0,0)

(1,2)

(3,5)

(4,7)

(6,10)

(8,13)

(9,15)

(11,18)

(12,20)

规律:(b[k]-a[k])为首项为0,公差为1的等差数列。

即a[0]=0,b[k]=a[k]+k;

a[k]是未在前面出现过的最小自然数.

当a<b时先手必败态可总结为a==(int)((b-a)*(1.0+sqrt(5))/2).

例题:http://poj.org/problem?id=1067

代码:

#include<iostream>
#include<math.h>
using namespace std;
int a,b;
int t;
int main()
{
    while(cin>>a>>b)
    {
        if(a>=b)swap(a,b);
        int temp=(b-a)*(1.0+sqrt(5.0))/2.0;
        if(a==temp)cout<<"0"<<endl;
        else cout<<"1"<<endl;
    }
}

3.尼姆博弈

有任意堆各若干个物品,两个人轮流从任意一堆取任意多的物品,规定每次至少取1个,最后取光者得胜。

若有k堆物品,每堆含a[i]个(i=1,2...k)

设temp=a[1]^a[2]^a[3]^...^a[k];(^表示异或)

先手必败态:temp==0.

 

posted @ 2021-02-08 15:32  chuliyou  阅读(318)  评论(0编辑  收藏  举报