如果实施得当,Bruteforce 在 n < 100 的情况下应该做得很好:下面的解决方案具有 O(n^4) 时间和 O(n^2) 内存复杂度。在现代 PC 上,10^8 次操作应该远低于 1 秒(特别是考虑到每个操作都非常便宜:加法和减法很少)。
一些观察
- 有 O(n^4) 个子矩形需要考虑,每个子矩形都可以是一个解决方案。
- 如果我们能在 O(1)(恒定时间)内找到每个子矩形中 1 和 0 的数量,我们将在 O(n^4) 时间内解决问题。
- 如果我们知道某个子矩形中 1 的数量,我们可以找到零的数量(通过区域)。
因此,问题简化为:创建数据结构,允许在恒定时间内找到每个子矩形中 1 的数量。
现在,假设我们有 sub-rectangle [i0..i1]x[j0..j1]
。即,它占据 i0 和 i1 之间的行和 j0 和 j1 之间的列。并让count_ones
函数计算子矩形中 1 的个数。
这是主要的观察:
count_ones([i0..i1]x[j0..j1]) = count_ones([0..i1]x[0..j1]) - count_ones([0..i0 - 1]x[0..j1]) - count_ones([0..i1]x[0..j0 - 1]) + count_ones([0..i0 - 1]x[0..j0 - 1])
与实际示例相同的观察结果:
AAAABBB
AAAABBB
CCCCDDD
CCCCDDD
CCCCDDD
CCCCDDD
如果我们需要在 D 子矩形 (3x4) 中找到 1 的数量,我们可以通过在整个矩形 (A + B + C + D) 中取 1 的数量,减去 (A + B) 中的 1 的数量来完成矩形,在 (A + C) 矩形中减去 1 的数量,并在 (A) 矩形中添加 1 的数量。(A + B + C + D) - (A + B) - (A + C) + (A) = D
因此,我们需要 table ,sums
对于每个包含多个 1 的 sub-rectangle 。
您可以在 O(n^2) 中创建此表,但即使是直接填充它的方法(对于每个并迭代区域的所有元素)也将是 O(n^4)。i
j
[0..i][0..j]
i
j
[0..i][0..j]
有了这张桌子,
count_ones([i0..i1]x[j0..j1]) = sums[i1][j1] - sums[i0 - 1][j1] - sums[i1][j0 - 1] + sums[i0 - 1][j0 - 1]
因此,时间复杂度达到了 O(n^4)。