一个 ???? × ????棋盘是要切成它的????·????单位正方形
Posted
技术标签:
【中文标题】一个 ???? × ????棋盘是要切成它的????·????单位正方形【英文标题】:An ???? × ???? chessboard is to be cut into its ????·???? unit squares 【发布时间】:2018-09-19 12:03:54 【问题描述】:一个???? × ????棋盘是要切成它的????·????单位正方形。在每个步骤中,您可以进行一次水平切割或一次垂直切割。第一次切割会将板子分成两个子板;之后,每次切割都会将剩余的一块子板分成两部分。切割的成本等于两个生成的子板中较小的一个中剩余的单位格数。例如,在 2 × 3 板上水平切割会产生两个 1 × 3 子板,成本为 3,而垂直切割会产生尺寸为 2 × 1 和 2 × 2 的子板,成本为 2。成本是累加的:一系列削减的成本等于它们各自成本的总和。描述一种算法来计算减少 ???? 的最小总成本× ????板进入其单位方块。证明其正确性并展示您对其时间复杂度的分析。
我的解决方案如下: 1. 我遵循贪婪的方法,检查 m(行)和 n(列)之间的最高值并进行切割。 2. 如果 m 较高,我进行垂直切割和其他水平切割。 3. 这给了我每一步的最低削减成本。 4. 我遵循分而治之并递归地遵循该方法,直到我有 m x n = 1 x 1
这似乎可行,但我正在努力推导出时间复杂度并证明我的算法的正确性。
我的时间复杂度表达式是 T(mn) = 2 T(mn/2) + theta(n)。
有人可以建议我如何做到这一点吗?
【问题讨论】:
这也是我所相信的。但无法从数学上证明这一点,因此没有明确说明。如果我能推导出复杂性,我可能会尝试证明这一点。 啊,我看错了问题。 【参考方案1】:最低费用为(n-1)*m+(m-1)*n
。您可以通过使m
水平切割每一张n-1
和n
垂直切割每一张m-1
来获得。也就是O(1)算法。
要切断一个单位方格,您需要在(n-1)*(m-1)
案例中支付至少 2 个,在(n-1)+(m-1)
中至少支付 1 个单位方格,您可以免费获得一个单位方格。这限制了以下的总体价格:
2*(n-1)*(m-1)+1*(n-1)+(m-1)+0*1 = 2*n*m-n-m = (n-1)*m+(m-1)*n
【讨论】:
仅供参考,你的和 Gassa 的似乎在 2-100 范围内匹配i,j
:repl.it/@gl_dbrqn/ExperiencedUnfoldedBrain
所以你是说这个场景的 O(mn)?
@AyanSengupta 这是 O(1),这是一个直接的公式!【参考方案2】:
这是一种动态编程方法,适用于O (m * n * (m + n))
。
对于子矩形的每个可能大小w * h
,计算将其切割成单个正方形的成本f (w, h)
。
选择第一个切割:w * h
切割成 a * h
和 b * h
,或切割成 w * c
和 w * d
。
切割成a * h
和b * h
的成本是min (a, b) * h + f (a, h) + f (b, h)
。
切割成w * c
和w * d
的成本是w * min (c, d) + f (w, c) + f (w, d)
。
综上所述,我们有
f (w, h) = min of
min for every a such that 0 < a < w
(let b = w - a)
min (a, b) * h + f (a, h) + f (b, h)
and
min for every c such that 0 < c < h
(let d = h - c)
w * min (c, d) + f (w, c) + f (w, d)
基地是f (1, 1) = 0
。
我们可以将所有f (w, h)
存储为一个二维数组,并在两个循环中自下而上计算它们,如下所示:
for w = 1, 2, ..., m:
for h = 1, 2, ..., n:
calculate f[w][h] by the formula above in O (w + h)
或者写一个带有记忆的递归函数。
这两种方法中的任何一种都适用于O (m * n * (m + n))
:我们必须计算m * n
值,并且每一种方法都至少计算为O (m + n)
值。
如果贪婪方法确实有效(我不知道),它会在 O (log m + log n) 中这样做。
通过直观的论证,例如,如果m = 17
和n = 23
,则必须考虑以下矩形:
17 * 23
17 * 11 and 17 * 12
8 * 11 and 8 * 12 and 9 * 11 and 9 * 12
8 * 5 and 8 * 6 and 9 * 5 and 9 * 6
4 * 5 and 4 * 6 and 5 * 5 and 5 * 6
4 * 2 and 4 * 3 and 5 * 2 and 5 * 3
2 * 2 and 2 * 3 and 3 * 2 and 3 * 3
1 * 1 and 1 * 2 and 2 * 1 and 2 * 2
1 * 1 again
如我们所见,矩形将采用(m / 2^x) * (n / 2^y)
的形式,其中x
和y
介于0
和log_2 (m + n)
之间,并且可以采用任何一种方式进行舍入。
【讨论】:
我试图在这里实现你的算法:repl.it/@gl_dbrqn/BlankFreshLicense 但我得到 13 的f(2,3)
,我认为答案是 7。我误解了什么吗?
@גלעדברקן 它的基本情况 = 0 而不是 1。我也犯了这个错误,但在五分钟的宽限期内将其删除。原来这是一个常见的;)。
@גלעדברקן 感谢您实际实施伪代码!另外,我想指出,使用 Python 3.2+ 或 some backport 到 Python 2.7,可以使用 lrucache
获得单行记忆。对于更大的尺寸,我们无论如何都应该这样做,以使解是多项式而不是指数。
酷。我只是想和贪婪比较,所以我不关心效率,但谢谢你的提示!
仅供参考,你的和 Yola 的似乎在 2-100 范围内匹配 i,j
:repl.it/@gl_dbrqn/ExperiencedUnfoldedBrain以上是关于一个 ???? × ????棋盘是要切成它的????·????单位正方形的主要内容,如果未能解决你的问题,请参考以下文章