动态编程:棋盘

时间:2013-02-27 04:10:25

标签: algorithm dynamic-programming

一辆车在标准的8乘8棋盘的左上角开始。两名玩家轮流向右或垂直向下移动车道,就像他们喜欢的那样多的方格。 不允许固定移动,玩家1先行。获胜者是将车放在右下角广场上的玩家。说谁将赢得并描述获胜策略。

我有上述陈述问题,我有兴趣了解其他人如何解决问题。我知道有办法计算车可以采取的不同路径。我尝试手工完成这个问题,看起来玩家2总是赢得,但我可能会想到它太简单了。以动态编程方式接近它似乎是一个很好的方法。无论如何,任何人都有任何见解,算法等等来解决这个问题!

4 个答案:

答案 0 :(得分:9)

enter image description here

H8 是一个胜利者的盒子,因此它上面和左边的所有内容都是输家框。

G7 (G8和H7)右侧和下方的所有内容都是输入框,因此它是赢家框。

G7 是一个胜利者的盒子,因此它上面和左边的所有内容都是输家框。

等等......

开始游戏的玩家只能选择进入失败者框,因此玩家2总是赢得

所有玩家2必须做的就是每次轮到他时移动到w框。

答案 1 :(得分:1)

玩家2总是赢得任何规模的棋盘。通过感应板的尺寸证明。

n = 1的情况可以忽略,所以从n = 2开始;很明显,玩家2在2x2板上获胜。

假设玩家2总是在大小为n或更小的棋盘上获胜。在尺寸为n + 1的棋盘上,玩家1移动到左列或顶行中的位置。然后玩家2移动到对角线上的位置(这是您需要的所有策略),然后是大小为n或更小的棋盘上的起始位置。

QED

答案 2 :(得分:1)

我认为值得注意的是,所描述的游戏实际上是一个Nim游戏,每个游戏有两个堆七个硬币。 Nim游戏的获胜者可以通过计算每堆中的硬币数量来确定。他们称之为Nim-sum,它给出了Sprague-Grundy函数的值。当Nim-sum为正数时,该位置即赢。所以考虑你的游戏:7 ^ 7 = 0,这是一个失败的位置。每个对角线位置都会丢失,因为无论x是什么,x^x始终为0 好消息是,使用这种技术,你可以在三维和任意大的空间,以及4维,5维等游戏(并赢得)这个游戏。

答案 3 :(得分:0)

获胜位置具有以下属性:

  • 所有终端位置都在赢。在这种情况下,位置(8,8)是获胜位置
  • 所有能够在一步中达到目标位置的位置都是胜利位置。 I.e。最后一行或列中的所有位置都是获胜位置
  • 如果我们能够进入失败的位置,那么我们就处于获胜位置,因为下一位玩家无法赢得比赛
  • 如果我们只能进入获胜位置,那么我们就处于亏损状态

考虑到这一点,我们可以创建一个算法,告诉我们当前位置是赢得位置还是失败位置。使用表(dpTable)来存储先前计算的结果将避免重复计算。

boolean isWinning(int x, int y) {
    if (dpTable[x][y] != null)
        return dpTable[x][y];

    // From the last row or the last column we can always win the game
    if (x == n || y == n)
        return true;

    for (int i = 1; x + i <= n; i++) {
        // Moving right
        if (x + i <= n && !isWinning(x+i, y) {
            dpTable[x][y] = true;
            return true;
        }

        // Moving down
        if (y + i <= n && !isWinning(x, y+i) {
            dpTable[x][y] = true;
            return true;
        }
    }

    dpTable[x][y] = false;
    return false;
}

isWinning(x, y)函数返回true从位置(x,y)开始,你可以通过最佳游戏赢得游戏,false当你无法开始时( x,y)和胜利。