zoukankan      html  css  js  c++  java
  • 每一个可以移动的棋子都要移动——Every-SG 游戏

    先看一个问题

    HDU 3595 GG and MM (Every_SG博弈)

    题目有N个游戏同时进行,每个游戏有两堆石子,每次从个数多的堆中取走数量小的数量的整数倍的石子。取最后一次的获胜。并且N个游戏同时进行,除非游戏结束,否则必须操作。 

    现在问题变成了,每次都必须在每个非空石子堆中选择。

    这个问题的核心在于:

    对于我们可以赢的单一游戏,我们一定要拿到这一场游戏的胜利!

    所以,我们只需要考虑如何让我们必胜的游戏尽可能长的玩下去。

    但是对手却不希望他必败的单一游戏玩的太久,这就是 Every-SG 游 戏不同于其他 SG 游戏的地方:一般的 SG 游戏只有胜与负之间的博弈, 而 Every-SG 游戏又添加了长与短之间的博弈,这使得 Every-SG 游戏更 有嚼头,更有味道。 

    最后的定理是显然的,最大的单一游戏步数如果是奇数的话那么肯定是先手取得进行最后一步。否则一定是对手取走最后一个棋子。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 1010
    
    int dp[N][N];
    
    int dfs(int p,int q)
    {
        if(p>q) swap(p,q);
        if(p==0)
        {
            dp[p][q] = 0;
            return 0;//必败
        }
        int k = q/p;
        int tp = q-p*k,tq = p;
        int flag = dfs(q-p*k,p);
        if(k==1)
        {
            dp[p][q] = dp[tp][tq]+1;
            return flag^1;
        }
        else
        {
            if(flag == 0)
            {
                dp[p][q] = dp[tp][tq]+1;
            }
            else dp[p][q] = dp[tp][tq]+2;
            return 1;
        }
    }
    
    int main() {
        int n;
        memset(dp,-1,sizeof(dp));
        while(cin>>n)
        {
            int mx = -1;
            for(int i=0;i<n;i++)
            {
                int p,q;
                cin>>p>>q;
                dfs(p,q);
                
                mx = max( mx,dp[min(p,q)][max(p,q)] );
            }
            if( (mx&1) ) printf("MM
    ");
            else printf("GG
    ");
        }
        return 0;
    }
    hdu3595
  • 相关阅读:
    服务端TextBox焦点事件
    Ajax进度条动画制作网址
    ADSL错误代码大全
    ASP.NET MVC Framework体验(5):路径选择(URL Routing)(转)
    为表添加一列IsUpload默认值为0
    ASP.NET MVC Framework体验(3):表单提交(转)
    .NET开源项目
    Vista文件共享
    mysql的to_days函数
    Samba简介
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5768340.html
Copyright © 2011-2022 走看看