将棋盘切成其单位正方形。在每个步骤中,您可以进行一次水平切割或一次垂直切割。第一次切割会将电路板分成两个子板;之后,每次切割将一个剩余的子板分成两个。削减成本等于两个所得子板中较小的剩余单位平方数。例如,2×3板上的水平切割产生两个1×3子板并且成本为3,而垂直切割产生尺寸为2×1和2×2且成本为2的子板。成本是附加的:一系列削减的成本等于其个人成本的总和。描述一种算法,用于计算将×板减少到单位平方的最小总成本。证明其正确性并展示您对其时间复杂性的分析。
我的解决方案如下: 我遵循贪婪的方法来检查m(行)和n(列)之间的最高点并进行切割。 2.如果m更高,我会做一个垂直切割而另一个是水平切割。 这给了我每一步的最低成本。 我遵循分而治之,并递归地遵循这个方法,直到我有m x n = 1 x 1
这似乎有效,但我正在努力的是得出时间复杂度并证明我算法的正确性。
我的时间复杂度表达式是T(m n)= 2 T(m n / 2)+ theta(n)。
有人可以建议我如何做到这一点吗?
答案 0 :(得分:2)
最低费用为(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
答案 1 :(得分:1)
这是一种动态编程方法,适用于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)
或者用memoization编写一个递归函数。
这两种方法中的任何一种都适用于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)
之间,并且四舍五入可以走任何一条路。