noip模拟赛 星空

分析:博弈论.

      单个博弈通用的解法是dp,设f[i][j][0]为如果在(i,j)Yuri先走能否获胜,f[i][j][1]为Chito能否获胜,对应的就是必胜态和必败态的转移.如果f[i-1][j][1],f[i-1][j-1][1],f[i][j-1][1]都为1,那么f[i][j][0]为0,否则为1,就是说如果Yuri接下来不论怎么走都是Chito赢,那么这就是一个必败态了.递推下去就好了.这里是把起点当作终点,每次只能向左,下,左下走,因为终点太多了.

      注意边界的处理!

#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int n, m;
bool f[1010][1010][2];

void init()
{
    f[1][2][0] = f[2][2][0] = f[2][1][0] = f[1][2][1] = f[2][2][1] = f[2][1][1] = 1;
    for (int i = 1; i <= 1000; i++)
        for (int j = 1; j <= 1000; j++)
            for (int k = 0; k < 2; k++)
                if (f[i][j][k] == 0)
            {
                int t = (k + 1) % 2;
                if (j - 1 >= 1 && f[i][j - 1][t] == 0)
                    f[i][j][k] = 1;
                if (i - 1 >= 1 && f[i - 1][j][t] == 0)
                    f[i][j][k] = 1;
                if (i - 1 >= 1 && j - 1 >= 1 && f[i - 1][j - 1][t] == 0)
                    f[i][j][k] = 1;
            }
}

int main()
{
    init();
    while (scanf("%d%d", &n, &m) && n && m)
    {
        if (f[n][m][0])
            puts("Yuri");
        else
            puts("Chito");
    }

    return 0;
}
原文地址:https://www.cnblogs.com/zbtrs/p/7765469.html