zoukankan      html  css  js  c++  java
  • POJ 3537 Crosses and Crosses

    POJ_3537

        对于连成3个X的状态我们是不好表示的,因此我们不妨退一步,看看在连成3个X之前都是什么样的状态,只要避免这样的状态出现就行了。

        画一下就会发现,实际上只有X_X和_XX_这样两种类型,其实想到这里就逐渐有眉目了,两个选手一定会避免走出上面的局面。因此当一个选手画了一个X之后,假设局面是12X34,其中数字代表空位,为了避免上面的情况出现,1、2、3、4这4个位置一定不能走,如果走了的话就必输了,因此我们就可以等效成画一个X之后X连同左右两边各两个格子都被拿掉了,这样就变成take and break类型的游戏了,具体的这类游戏的一些模型可以参考《Game Theory》这篇论文。

        于是,我们只要把连续的一段格子看成一个状态就可以了,每次画X的时候要么就是在某一端去掉一些格子,要么就是在中间去掉5个格子并把剩下的格子分成左右两部分,再要么如果n小的话就全被去掉了。然后用记忆化搜索求得各个状态的sg函数值即可。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 2010
    int sg[MAXD], N;
    int dfs(int n)
    {
    if(sg[n] != -1)
    return sg[n];
    if(n <= 3)
    return sg[n] = 1;
    int i, j, k, h[MAXD];
    memset(h, 0, sizeof(h));
    for(i = 1; i <= n; i ++)
    {
    if(i > 3)
    {
    if(i < n - 2)
    h[dfs(n - i - 2) ^ dfs(i - 3)] = 1;
    else
    h[dfs(i - 3)] = 1;
    }
    else
    {
    if(i < n - 2)
    h[dfs(n - i - 2)] = 1;
    else
    h[0] = 1;
    }
    }
    for(i = 0; h[i]; i ++);
    return sg[n] = i;
    }
    int main()
    {
    memset(sg, -1, sizeof(sg));
    while(scanf("%d", &N) == 1)
    printf("%d\n", dfs(N) ? 1 : 2);
    return 0;
    }


  • 相关阅读:
    Java中的多线程你只要看这一篇就够了
    模板CodeTemplate
    mybatis_mysql
    Kettle 使用Json输入
    图解ByteBuffer
    双队列缓存
    log4j.properties配置详解与实例
    Kettle 使用Json输入
    JSON响应端模拟测试
    使用Kettle导出excel
  • 原文地址:https://www.cnblogs.com/staginner/p/2388280.html
Copyright © 2011-2022 走看看