寻找总和最大的子矩阵
Possible Duplicate:
Finding a submatrix with the maximum possible sum in O(n^2)
I have an NxN matrix. I want to find out an MxM submatrix, with largest sum of its elements, of the above matrix.
What is the efficient algorithm for this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我有一个算法,在放大 M 时以恒定时间运行,在放大 N 时以二次时间运行。
第一个子矩阵照常计数。存下这笔钱。然后向右移动一行字段 - 两个 MxM 矩阵重叠,因此您只需将两个不重叠的列相加即可。把所有的钱都存起来。现在您可以选择该行的最大总和。
移至下一行。还记得节省的金额吗?第一行和第二行的 MxM 矩阵再次重叠,因此您可以将 MxM 矩阵的第一行和最后一行相加,并计算第二行中的第一个总和。
现在转到第二行的第二个和。执行与上面相同的操作,但您会发现第二行中第一个 sum 和第二个 sum 的最后一行再次重叠。
我知道这有点令人困惑,如果你不明白,请告诉我,我会画一些图。该算法基于 这个答案。
编辑:我知道我承诺过图片,但这应该足够了:
这是四个子矩阵,A、B、C、D,定位如下:
首先计算 A 子矩阵的总和:sum(A)。这里没有优化。现在您想要计算 B 的总和:sum(B)。您可以执行与 A 中相同的操作,但请注意 A 和 B 重叠。因此,您将 sum(A) 分配给 sum(B),计算垂直向量
A AC AC AC AC
的总和,并从 sum(B) 中减去 if,然后计算垂直向量的总和B BD BD BD BD
并将其添加到 sum(B)。你有总和(B)。现在您可以继续计算整个第一行 submatices。
移至第二行:matices C 和 D。您不必对整个 matice C 求和,因为在上一行中,您保存了 sum(A)。注意它们再次重叠。您只需添加 A 和 C 之间的差:
您就得到了 sum(C)。现在你可以像这样得到 sum(D):
但是比较 subD 与 subC 以及 addD 与 addC。它们重叠!所以你可以这样做:
你会看到,我们不是对一个子矩阵的计算和进行 25 次添加,而是进行 6 次添加。对于 MxM 的每种可能大小,我们对第一个子矩阵进行 MxM 次添加,对第一行进行 M*2+2 次添加以及第一列和其余 6 个附加项。
I have an algorithm that runs in constant time when enlarging M and quadratic time when enlarging N.
First submatrix count as usual. Save the sum. Then move one row field right - the two MxM matrices overlap, so you can just just sum the two non overlaping columns. Save all the sums. Now you can choose the largest sum for the line.
Move to next line. Remember the saved sums? The MxM matrices of first and second lines overlap again, so you can just sum the first and the last lines of MxM matrices and compute first sum in second line.
Now move to the second sum of the second line. Do the same thing as above, but you find out that the last lines of first sum and the second sum in the second row overlap again.
I know it is kind of confusing, if you don't get it, let me know I will draw some picture of it. The algorithm is based on paper in this answer.
EDIT: I know I promised picture, but this should be enough:
These are four submatices, A, B, C, D, positioned like this:
First you count the sum of the A submatrix: sum(A). No optimizations here. Now you want to count the sum of B: sum(B). You can do the same as in A, but notice that A and B overlap. So you assign sum(A) to sum(B), count the sum of vertical vector
A AC AC AC AC
and substract if from sum(B), then count the sum of vertical vectorB BD BD BD BD
and add it to sum(B).You have sum(B). Now you can continue and compute the whole first line of submatices.
Move to the second line: matices C and D. You don't have to sum the whole matice C, because in previous line, you saved sum(A). Notice they overlap again. You just need to add the difference between A and C:
You have sum(C). Now you can get sum(D) like this:
but compare subD vs. subC and addD vs addC. They overlap! So you can do it this way:
You see that instead of 25 aditions for comuting sum of one submatrix, we do 6. For every possible size of MxM, we have MxM aditions for first submatrix, M*2+2 aditions for first row and for first column and 6 aditions for the rest.