trominoes 算法的复杂性

Posted

技术标签:

【中文标题】trominoes 算法的复杂性【英文标题】:Complexity of trominoes algorithm 【发布时间】:2015-04-25 05:33:12 【问题描述】:

(分而治之)是什么或应该是什么?为什么?

我得到了一个 2^k * 2^k 大小的棋盘,其中一个棋子被随机移除,使其成为有缺陷的棋盘。任务是用“trominos”填充,这是一个由 3 个瓷砖组成的 L 形图形。

平铺问题

– 输入:一个 n x n 方板,其中一个 1 x 1 方格 缺失,其中对于某些 k ≥ 1,n = 2k。

– 输出:使用 tromino 的棋盘拼贴,三方格 通过从 2 x 2 中删除右上角的 1 x 1 角获得 正方形。

– 您可以旋转 tromino,以平铺棋盘。 基础案例:可以平铺一个 2 x 2 的正方形。

归纳:

– 将正方形分成 4 个,n/2 x n/2 个正方形。

– 将tromino 放在tromino 没有的“中心” 将 n/2 x n/2 正方形重叠,该正方形之前以 1 x 1 的比例丢失 正方形。

– 以感应方式求解四个 n/2 × n/2 板中的每一个。

【问题讨论】:

你应该也提供算法,或者至少提供一个简单描述的链接。 请更具体地了解倒数第二个步骤“将 tromino 放置在“中心”,其中 tromino 不与之前遗漏的 n/2 x n/2 正方形重叠1 乘 1 方格。” - 你也可以包括参考en.wikipedia.org/wiki/Tromino 当您将棋盘分成 4 个部分时,其中一个部分缺少图块。您将 tromino 的一部分放入其他部分中。例如,如果您在第一部分缺少瓷砖,则将 tromino 元素放在左下位置的第二部分,左上位置的第三部分和右上位置的第四部分。 对你来说,你的意思是四块较小的板,一半尺寸边长一半,这将是尺寸的四分之一我>? 【参考方案1】:

该算法运行时间为 O(n2) = O(4k)。要了解原因,请注意您的算法对每个网格执行 O(1) 工作,然后对宽度和高度为原始大小一半的网格进行四次子调用。如果我们使用 n 作为参数表示网格的宽度或高度,我们有以下递归关系:

T(n) = 4T(n / 2) + O(1)

根据主定理,这解决了 O(n2)。由于n = 2k,我们看到n2 = 4k,所以这也是O(4k) 如果你想使用 k 作为你的参数。

我们也可以让 N 表示棋盘上的方格总数(因此 N = n2),在这种情况下,子调用是四个大小为 N / 4 的网格。这给出了复发

S(N) = 4S(N / 4) + O(1)

这解决了O(N) = O(n2),证实了上面的结果。

希望这会有所帮助!

【讨论】:

看起来不对:板子分为4,所以应该是T(n) = 4T(n / 4) + O(1)。子网格是原始大小的 1/4,而不是一半。 子网格确实是1/4的原始大小,但边长是n/2。重复率以板的边长表示,而不是板的大小。 @Codor - 也许吧,但答案还不清楚,特别是因为它说“四个子调用到原始大小的一半的网格”。如果你说网格 size,那并不仅仅意味着边长。 @IVlad 是的,公式有点不清楚。 @IVlad 我已经更新了答案以更清楚地定义 n 是什么。我还使用 N = n^2 作为平方总数进行了第二次分析。如果这看起来更好,请告诉我!【参考方案2】:

据我了解,复杂度可以确定如下。让T(n) 表示求解边长为n 的板所需的步数。从上面原始问题的描述中,我们有

T(2) = c

其中c 是一个常量并且

T(n) = 4*T(n/2) + b

其中b 是放置tromino 的常数。使用master theorem,运行时绑定是

O(n^2)

通过案例 1。

【讨论】:

这个递归实际上是O(n^2) @IVlad 感谢您的评论,我以某种方式混淆了它。我将编辑答案。【参考方案3】:

我将尝试提供不太正式的解决方案,但不使用主定理。

– 将tromino 放置在“中心”,其中tromino 不会与之前错过的n/2 x n/2 方块重叠。

我猜这是O(1) 操作?在这种情况下,如果n 是板子大小:

T(1) = O(1)
T(n) = 4T(n / 4) + O(1) = 
     = 4(4T(n / 4^2) + O(1)) + O(1) = 
     = 4^2T(n / 4^2) + 4*O(1) + O(1) =
     = ... =
     = 4^kT(n / 4^k) + 4^(k - 1)*O(1)

但是n = 2^k x 2^k = 2^(2k) = (2^2)^k = 4^k,所以整个算法是O(n)

请注意,这与@Codor 的回答并不矛盾,因为他将n 视为板的边长,而我将其视为整个区域。

如果中间步骤不是O(1)而是O(n)

T(n) = 4T(n / 4) + O(n) =
     = 4(4*T(n / 4^2) + O(n / 4)) + O(n) =
     = 4^2T(n / 4^2) + 2*O(n) = 
     = ... =
     = 4^kT(n / 4^k) + k*O(n)

我们有:

k*O(n) = n log n because 4^k = n

所以整个算法就是O(n log n)

【讨论】:

【参考方案4】:

每个放置的 tromino 做 O(1) 工作。由于要放置 (n^2-1)/3 个trominos,因此该算法需要 O(n^2) 时间。

【讨论】:

以上是关于trominoes 算法的复杂性的主要内容,如果未能解决你的问题,请参考以下文章

如何解决这个 tromino 平铺问题?

LeetCode 790. Domino and Tromino Tiling

算法的计算复杂性

算法概述-第一节:算法基本概念和算法复杂性分析

解决时间复杂性,算法产生了什么?

算法设计与分析——算法复杂性分析