博弈论



一、Nim游戏
1、判断局面胜负  
 poj2234 
#include <cstdio>
int M,i;
long long ai,ans;
int main()
{
   while (scanf("%d",&M)!=EOF)
   {
      ans=0;
      for (i=1; i<=M; i++)
       {scanf("%I64d",&ai);
       ans=ans^ai;
       }
      if (ans)printf("Yes\n");
        else printf("No\n");
   }
} 


2、判断局面胜负 若先手胜 统计策略数

poj2975 
#include <cstdio>
long long n,t,ans,i;
long long a[1000];
int main()
{
   while (scanf("%lld",&n))
   {
       if (!n) break;
       t=0;
       ans=0;
       for (i=0;i<n;i++)
        {
           scanf("%lld",&a[i]);
           ans^=a[i];
        }
      if (ans==0) { printf("0\n"); continue;}
      for (i=0; i<n;i++)
        if ((ans^a[i])<=a[i]) ++t; //wa
      printf("%lld\n",t);
   }
}       



二、威佐夫博奕
第i个奇异局势a,b之差为i,如果字典顺序寻找,则(a,b)中的a,为之前奇异局势中未出现的最小的自然数;
数学家已经给出了我们a的通项公式,即ai=[i*(1+√5)/2](方括表示下取整),bi=ai+i,。
终极公式 An = [(1 + sqrt(5)) / 2 * n], Bn = [(3 + sqrt(5)) / 2 * n]; 

poj 1067 判断奇异局势

#include <cstdio>
#include <cmath>
double x;
long long ak,bk;
void swap(long long &a,long long &b) { a=a^b; b=a^b; a=a^b; }
int main()
{
    x=(1+sqrt(5.0))/2;
    while (scanf("%I64d%I64d",&ak,&bk)!=EOF)
     {
       if (ak>bk) swap(ak,bk);
       long long k=bk-ak;
       if (ak==(long long)(k*x)) printf("0\n"); //奇异局势 先手必败
         else printf("1\n");
       }
}


三、 巴什博弈( Bash Game

定义:只有一堆石子,两人轮流取,最少取一个,最多取m个,最后去完者为胜。

思考:

①当石子个数n=0时为必败点;(根据题意得来)

②当石子个数0<n<=m时为必胜点;(可以到达状态①)

③当石子个数n=m+1时为必败点;(只能到达状态②)

④当石子个数m+1<n<=(m+1)+m时为必胜点;(可以到达状态③)

⑤当石子个数n=(m+1)+m+1时为必败点;(只能到达状态④)

……

当n为m+1的整数倍时为必败点

把n写成这样的格式:n=r*(m+1)+s;

只要s不为0,即可胜


四、其他模型

1、一个数  开始为 两个人轮流把它乘  2~9   第一个把这个数乘超过 n 的获胜
poj 2505 
#include <cstdio>
#include <cmath>
long long n;
int main()
{
   while (scanf("%lld",&n)!=EOF)
   {
     while (1)
     {
       if (n%9==0) n/=9; else n=n/9+1; //注意这里 不这样写就Wa了= =
       if (n==1){ printf("Stan wins.\n"); break;}
       if (n%2==0) n/=2; else n=n/2+1;//
       if (n==1){ printf("Ollie wins.\n");break;}
     }
   }
}

2、 n 个位置围个圈,每个位置一个硬币,每次可以取 1 个或者位置相邻的 2 个硬币,没硬币取的败,问先手 胜负。

poj 2484
#include <cstdio>
long n;
int main()
{
  scanf("%ld",&n);
  while (n)
  {
     if (n<=2) printf("Alice\n");
        else printf("Bob\n");
     scanf("%ld",&n);
  }
}


五、关于SG函数
 有顺序的直接for求解  ,无顺序的DFS或者其他什么的


ygy大神的课件

博弈论_第1张图片


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