博弈论初步

一。巴什博弈

只是最简单的博弈了,只简单说一下满足条件,一堆总数为n个,每次可以取1-m个石头。  核心是n=(m+1)*r+s;也就是说用n%(m+1) 判断是否等于0即可。

例题:hdu 1846 

巴什博弈

int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        int a,b;
        cin>>a>>b;
        int t=a%(b+1);
        if(t>=1)
        {
            cout<<"first"<

二。斐波那契博弈。

要求是在一堆里,轮流取石头,每次取的石头要求在1-上一次对手取的石头的2倍之间  包括两个端点,核心是把这个数分解成斐波拉契数列,换句话说,判断这个n是否是斐波拉契数即可。

例题:hdu2516

斐波那契博弈

int main()
{
    int n;
    int a[maxn];
    a[0]=2;
    a[1]=3;
    for(int i=2;i<=50;i++)
    {
        a[i]=a[i-1]+a[i-2];
    }
    while(cin>>n,n)
    {
        int flag=0;
        for(int i=0;i<=50;i++)
        {
            if(n==a[i])
            {
                puts("Second win");
                flag=1;
                break;
            }
        }
        if(!flag)
        {
            puts("First win");
        }
    }
}

三。威佐夫博弈。

要求是两堆石头,两个人轮流从某一堆同时从两堆中取同样多的物品。最少一个,多则无限。

这个博弈的关键在于一个黄金分割数。


就要提到一种叫奇异局势。



意思是B-A(当然保证B>A) A=黄金分割数*(B-A)的话就是奇异局势。核心就在这里。


例题:poj 1067

威佐夫博弈

int main()
{
    int a,b;
    while(cin>>a>>b)
    {
        if(a>b)
            swap(a,b);
        int c=floor((b-a)*((sqrt(5.0)+1)/2));
        if(c==a)
        {
            puts("0");
        }
        else
        {
            puts("1");
        }
    }
}


四。尼姆博弈。要求是n堆里面,取一堆任意多的物品。每次取一个,多者不限。

博弈论初步_第1张图片


博弈论初步_第2张图片



核心也就是异或。



例题:hdu 1850

尼姆博弈

int main()
{
    int m;
    while(cin>>m,m)
    {
        int ans=0,sum=0;
        int a[maxx];
        for(int i=1;i<=m;i++)
        {
            cin>>a[i];
            ans^=a[i];
        }
        if(ans==0) puts("0");
        else
        {
            for(int i=1;i<=m;i++)
            {
                int k=ans^a[i];
                if(k


五。SG值。 


博弈论初步_第3张图片

例题:hdu 1847

SG值


#include 
//#include 
//#include 
//using namespace __gnu_pbds;
using namespace std;



#define pi acos(-1)
#define endl '\n'
#define me(x) memset(x,0,sizeof(x));
#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL LINF=0x3f3f3f3f3f3f3f3fLL;
const int dx[]={-1,0,1,0,-1,-1,1,1};
const int dy[]={0,1,0,-1,1,-1,1,-1};
const int maxn=1e3+5;
const int maxx=2e5+100;
const double EPS=1e-7;
const int mod=1000000007;
templateinline T min(T a,T b,T c) { return min(min(a,b),c);}
templateinline T max(T a,T b,T c) { return max(max(a,b),c);}
templateinline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}
templateinline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}
//typedef tree,rb_tree_tag,tree_order_statistics_node_update> rbtree;
/*lch[root] = build(L1,p-1,L2+1,L2+cnt);
    rch[root] = build(p+1,R1,L2+cnt+1,R2);中前*/
/*lch[root] = build(L1,p-1,L2,L2+cnt-1);
    rch[root] = build(p+1,R1,L2+cnt,R2-1);中后*/
long long gcd(long long a , long long b){if(b==0) return a;a%=b;return gcd(b,a);}


int sg[maxx];
int a[100];
int mex(int x)
{
    if(sg[x]!=-1) return sg[x];
    int vis[maxn];
    me(vis);
    for(int i=0;i<=10;i++)
    {
        int temp=x-a[i];
        if(temp<0) break;
        sg[temp]=mex(temp);
        vis[sg[temp]]=1;
    }
    for(int i=0;;i++)
    {
        if(!vis[i])
        {
            sg[x]=i;
            break;
        }
    }
    return sg[x];
}


int main()
{
    int n;
    a[0]=1;
    for(int i=1;i<=10;i++)
    {
        a[i]=a[i-1]*2;
    }
    while(cin>>n)
    {
        memset(sg,-1,sizeof(sg));
        if(mex(n)) puts("Kiki");
        else
            puts("Cici");
    }
}





你可能感兴趣的:(博弈论)