【问题标题】:Polynomial time solution for Tetris Puzzle俄罗斯方块拼图的多项式时间解
【发布时间】:2015-11-01 16:38:57
【问题描述】:

这是一个基于Tetris 的谜题。在这个谜题中,我们给出了接下来 n 块将从顶部掉下来的序列。我们的工作是在 GameOver 之前最大化分数。对于一般俄罗斯方块,没有已知的多项式时间算法,但在这个谜题中,只允许使用 I(直)四联骨牌。虽然不允许旋转它们。

以下是限制条件:

  • 电路板是一个宽 x 高的矩形
  • 我们得到了下 n 个四联骨牌的序列
  • 只允许使用四联牌(水平或垂直)
  • 不允许件旋转
  • 行在填满时被清除
  • 董事会最初是空的
  • 每清除一行可获得 1 分。
  • 当四联骨牌堆叠到比赛场地顶部时,游戏结束。

找出可以获得的最高分。

例子:

8 x 6 板。接下来的7个四联体是[——,|,|,——,|,——,|],其中'——'代表水平四联体,|代表垂直四联体。

在这种情况下,最大可能得分为 3,使用以下策略('.' 代表空棋盘,'#' 代表四联棋子的一部分)。

Initially:
........
........
........
........
........
........
1st move:
........
........
........
........
........
####....
2nd Move:
........
........
.......#
.......#
.......#
####...#
3rd Move:
........
........
......##
......##
......##
####..##
4th Move:
........
........
......##
......##
####..##
####..##
5th Move:
........
........
.....###
.....###
####.###
####.###
6th Move:
........
........
.....###
####.###
####.###
####.###
7th Move:
........
........
....####
########
########
########  // bottom 3 rows are cleared so score is 3
final state:
........
........
........
........
........
....####

即使是我能想出的最佳算法也需要指数级的时间来保存当前板子顶层的状态(即每列的高度)。所以这个算法需要O((H^W)*n)time,因为每一列都有H个高度的可能性。

这可以使用动态规划或一些贪心算法在多项式时间内解决吗?

【问题讨论】:

  • 这是你的作业吗?
  • 对我来说可能已经晚了:如何从左侧堆叠水平的,从右侧堆叠垂直的?应该在示例中给出三个清除的行,并从贪婪的启发式开始。
  • @Gene。不,我找到了 dp 解决方案,用于更一般的情况,它是 W 上的指数。我想可能会进一步简化并只允许 2 种类型的四联胺我可以在多项式时间内解决它,但我不能。
  • 启发式方法可能会奏效,因为问题相对简单。您需要根据板子的大小设计一组规则(例如,如果板子很宽,请将“--”并排放置,如果不是,则将它们堆叠起来)。
  • 解决方案是否允许将零件侧向引导到板上由于悬垂而无法从顶部进入的孔中?例如,在一块序列为||-||| 的 5 宽度板上,如果要清除 4 行(而不是1 或 0)。

标签: algorithm dynamic-programming puzzle greedy tetris


【解决方案1】:

我会尝试猜测:

棋盘是一个宽 x 高的二进制矩阵。

四联骨牌的序列是一个长度为n的二进制字符串s,1代表垂直,0代表水平。

让我们试试决策问题:给定一个任意棋盘和任意长度为 n 的四联板序列 s,是否有获胜的移动序列?

在每一步你最多可以做 W 选择:tetronmino 的位置。

使用以下算法检查给定的棋盘和四联牌序列是否存在移动检查 CanWin(B(n)) 的获胜序列:

 CanWin(B(i)):
   if Filled(B(i)) return false
   if (i == n and not Filled(B(i))) return true
   choose position in 0..W-1
   B(i+1) = UpdateBoard(Bi, s(i+1), position)
   return CanWin(B(i+1))

您可以通过检查顶行来检查板是否填充 O(W)。您可以通过检查 O(H) 中的冲突来更新电路板。 [需要考虑行擦除] 然后你可以判断O(nW(H)^W)中是否有获胜序列。

如果你记得哪个猜测是最好的父母指针,那么你就有一个获胜的策略。

现在算法是指数的,但您可以memoized 使用大小最多为 2^(W x H + 1) x W 的数据集进行递归。

从现在开始,我不知道如何计算被记住的调用次数。

备注:

  • 在此版本中,您无法在从顶部坠落期间引导四联牌。

  • 由于行擦除,递归中可能存在循环。您也许应该从您的问题中删除此规则。

  • 文章Tetris is Hard, Even to Approximate在结论中推测,只有一个水平/垂直四联格的俄罗斯方块是多项式时间。

【讨论】:

    【解决方案2】:

    我无法理解如何比指数时间最坏的情况更快地做到这一点。一些想法:

    游戏在以下任一情况下结束:放置 n 个四联骨牌个放置的四联骨牌超过失败等级。

    可能比指数时间更快地找到解决方案。由于累积积分的唯一方法是清行,而且每次清零多少行都是每行1分,因此可能存在多种解决方案。如果在放置 n 块四块骨牌后没有四块骨牌留在棋盘上,则不可能有更高的得分解决方案(以更少的步数完成不会获得奖励积分)。在最好的情况下,可以在线性时间内找到解决方案(放置 n 个四联骨牌),最坏的情况是指数级的。

    显然我们可以采用一些技巧或模式来加快速度。例如,如果可以证明 x 数量的 tetromino 可以清除棋盘,那么如果 x 除以 n,我们就有了解决方案。

    【讨论】:

      猜你喜欢
      • 2011-07-30
      • 1970-01-01
      • 2018-06-06
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      • 2013-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多