博弈论可以到学校好好给学弟们讲讲hh.
sg函数是博弈解题的一个工具,就拿今天这个题目当例子来说吧.
题目描述:给定一张NM的矩形网格纸,两名玩家轮流行动。在每一次行动中,可以任选一张矩形网格纸,沿着某一行或某一列的格线,把它剪成两部分。首先剪出1*1的格纸的玩家获胜。两名玩家都采取最优策略行动,求先手是否能获胜。
就是这样的,怎么做呢?首先我们很容易知道(2,2),(2,3),(3,2)这三个点先手必败.
然后我们根据博弈可以转化到路径的形式,sg[n][m]为0代表先手必输,对于每个点,其实都已经确定了必赢还是必输,这个题的图只有一幅,sg[x][y]=0的点一定是必输点.其他点一定是必胜点.
代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N=205;
int sg[N][N];

inline int SG(int n,int m)
{
    int f[N];
    memset(f,0,sizeof f);
    if(sg[n][m]!=-1)    return sg[n][m];
    for(int i=2;i<=n-2;i++) f[SG(i,m)^SG(n-i,m)]=1;
    for(int i=2;i<=m-2;i++) f[SG(n,i)^SG(n,m-i)]=1;
    int p=0;
    while(f[p]) p++;
    return sg[n][m]=p;
}

int main()
{
    int n,m;
    for(int i=1;i<=N-1;i++)
    {
        for(int j=1;j<=N-1;j++)
        {
            sg[i][j]=-1;
        }
    }
    sg[2][2]=0; sg[2][3]=0; sg[3][2]=0; 
    while(cin>>n>>m)
    {
        SG(n,m)?puts("WIN"):puts("LOSE");    
    }
    return 0;
}