消除街区计划

时间:2015-08-06 15:16:53

标签: c++ algorithm design-patterns multidimensional-array

今天早上我正在进行技术讨论,主席邀请我和他一起玩游戏。

有一系列'n'个区块,每个玩家都可以选择2个相邻的区块并将其标记为已填充。玩家继续这样做直到最后一对相邻的区块被填满。填写最后一对的人输掉比赛。

问题:我后来被问到是否可以在C ++上构建一个程序,该程序将为每个玩家提供一些提示,以便根据董事会的当前状态确定哪些可用的对可以给予他最大的获胜机会。

我确信这有一个设计/算法。只是我无法识别它。能否帮助我找到解决问题的可能方法。是否存在涵盖类似问题的既定问题(如分区问题)

1 个答案:

答案 0 :(得分:0)

我认为我们可以使用动态编程。让:

dp[n, 1] = true    if player 1 has a certain winning strategy for n blocks
           false   otherwise

dp[n, 2] = same for player 2

玩家1首先移动。

我们有:

dp[0, 1] = dp[0, 2] = true
dp[1, 1] = dp[1, 2] = true
dp[2, 1] = false, dp[2, 2] = true

然后重复考虑当前玩家占据第一和第二个区块,第二个和第三个等等。这意味着对手必须处理两堆大小:

0, n - 2
1, n - 3
2, n - 4
...

k, n - k - 2, k = 0 to n - 2

对于一个获胜的玩家,他们必须至少有一个最终结果的获胜策略。

对于当前的获胜者,他必须能够让对手进入dpfalse的状态。所以我们有:

dp[n, 1] =       OR         {NOT (dp[k, 2] OR dp[n - k - 2, 2])} 
           0 <= k <= n - 2

dp[n, 2] =       OR         {NOT (dp[k, 1] OR dp[n - k - 2, 1])} 
           0 <= k <= n - 2

如果我们可以让下一个玩家进入他没有某种获胜策略的状态,那么dp[n, 1]的含义就是真的。当然,我们的对手也会发挥最佳状态。

dp[k, 2] OR dp[n - k - 2, 2]

如果玩家2拥有两个桩的获胜策略,则返回true。如果是,我们不想选择那个,所以我们否定它,返回false。如果不是,通过否定它我们就会成真,并且通过OR所有值,我们会发现是否存在真实,我们可以选择。