zoukankan      html  css  js  c++  java
  • poj2311

      博弈论——sg,mex

    sg性质:1.在末态的状态点为N态。

         2.P态的下一步有一个是N态

         3.N态的下一步全部是P态。

    当然这是对于单点一个游戏的情形,也相当于NIM只有一堆石子。

    mex(minimal excludant),很俗地可以解释为:mex{S}表示S集合中从0开始,最小未出现的数字。

    关于sg与mex的关系,可以引用这里http://www.cnblogs.com/Knuth/archive/2009/09/05/1561007.html的一段话:

    对于一个给定的有向无环图,定义关于图的每个顶点的Sprague-Garundy函数g如下:g(x)=mex{ g(y) | y是x的后继 }。

    来看一下SG函数的性质。首先,所有的terminal position所对应的顶点,也就是没有出边的顶点,其SG值为0,因为它的后继集合是空集。然后对于一个g(x)=0的顶点x,它的所有后继y都满足g(y)!=0。对于一个g(x)!=0的顶点,必定存在一个后继y满足g(y)=0。

    以上这三句话表明,顶点x所代表的postion是P-position当且仅当g(x)=0(跟P-positioin/N-position的定义的那三句话是完全对应的)。

    关于sg叠加的效果,很神奇发现它们满足sg(G) = sg(G1)^sg(G2)^……^sg(Gn)。对于与博弈有关的核心就是这些了。多刷刷题,自然心里就明了了。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 int sg[210][210];
     6 int stamp[210*210]={0},stamps=1;
     7 int sgx(int r,int c){
     8     stamps++;
     9     for(int i=2;i<=r-i;i++)  // 1 c(只有一行)【r-1 c】 不能被继续,故需要从2开始。
    10         stamp[sg[i][c]^sg[r-i][c]] = stamps;
    11     for(int i=2;i<=c-i;i++)
    12         stamp[sg[r][i]^sg[r][c-i]] = stamps;
    13     for(int i=0;;i++)
    14     if(stamp[i] < stamps)
    15     {
    16         sg[r][c] = i;
    17         break;
    18     }
    19     return sg[r][c];
    20 }
    21 int main()
    22 {
    23     for(int i=1;i<210;i++)
    24         sg[1][i] = sg[i][1] = 1;
    25 
    26     for(int i=2;i<210;i++)
    27       for(int j=i;j<210;j++)
    28         sg[i][j] = sg[j][i] = sgx(i,j);
    29     int n,m;
    30     while(scanf("%d%d",&n,&m) != EOF){
    31         if(sg[n][m]) printf("WIN
    ");
    32         else printf("LOSE
    ");
    33     }
    34     return 0;
    35 }
  • 相关阅读:
    第六次作业
    第五次作业
    第四次作业
    第三次作业
    第二次作业 计科一班程晨
    第一次作业 计科一班程晨
    第七次作业
    第五次作业
    第四次作业
    第三次作业
  • 原文地址:https://www.cnblogs.com/karlvin/p/3203204.html
Copyright © 2011-2022 走看看