请有人建议使用动态编程方法来解决SPOJ问题“标准问题”,链接: - http://www.spoj.com/problems/ASTDPROB/
问题陈述: 给定一个大小为NXM的布尔矩阵。对于int low low,high类型的所有Q查询,找到最大区域子矩形,它只有零,位于编号为low和high的行之间。
1 ≤ N, M ≤ 1000
1 ≤ Q ≤ 10^6
我需要一个O(n ^ 2)或O(n ^ 2 * log n)dp算法。
直到我的方法如此
请为第2步建议任何优化?
任何采用更有效方法的人,请分享一下。
提前致谢。
答案 0 :(得分:2)
让M
成为0
和1
s的矩阵。
计算矩阵S
,其中S[k][l]' is the number of consecutive zeros up from
M [k] [l]`。这将需要O(n ^ 2)。
现在,对于给定的查询(lo,hi)
,您可以从第lo
行转到第hi
行。对于每一行line
,按以下方式查找从line
到hi
的最大矩形:
- 通过p
使用指针S[line]
并跟踪可能的高度。
例如,假设S[line] = [1,2,2,1,5,6,9,2,1,4]
。当p = 5
你应该有一个元组列表,如:
W = [0,4,5]
从中你可以计算在p==6
处完成的矩形的大小:
max(S[line][W[0]], hi-lo+1) * (p-W[0] + 1) = 6
max(S[line][W[1]], hi-lo+1) * (p-W[1] + 1) = 10
max(S[line][W[2]], hi-lo+1) * (p-W[2] + 1) = 6
编辑:嗯,似乎有更复杂的解决方案,至少在计算S
之后。您可以将其视为问题H:
http://www.informatik.uni-ulm.de/acm/Locals/2003/html/judge.html
这里还有一个相关的SO问题 Maximize the rectangular area under Histogram
编辑:如何使用直方图的想法。
让M
具有以下结构
1010100101
0001001001
0001000010
0100000000
然后S
可以自下而上计算,在这种情况下是
0301041020
3230330310
2120222202
1011111111
现在要找到一条从某条线开始直到最后的矩形,我们使用'直方图问题'。对于第二行,我们有:3230330310
,这对应于表格的直方图
X X XX X
XXX XX X
XXX XX XX
在此处查找最大的矩形会给出起始问题中最大的矩形。
Complecity:O(n) - 直方图算法。现在,对于每个查询,我们最多检查n
行,我们有q
个查询,因此:O(n^2 q)