一个 ???? × ????棋盘是要切成它的????·????单位正方形

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-1n垂直切割每一张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 * hb * h,或切割成 w * cw * d。 切割成a * hb * h 的成本是min (a, b) * h + f (a, h) + f (b, h)。 切割成w * cw * 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 = 17n = 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) 的形式,其中xy 介于0log_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

以上是关于一个 ???? × ????棋盘是要切成它的????·????单位正方形的主要内容,如果未能解决你的问题,请参考以下文章

棋盘游戏

滚动背景图片切成两半 - cocos2d

马踏棋盘算法详解

kuangbin专题每日一题 棋盘问题 POJ-1321

kuangbin专题每日一题 棋盘问题 POJ-1321

kuangbin专题每日一题 棋盘问题 POJ-1321