查找具有最大总和的子矩阵

时间:2011-03-23 08:13:21

标签: c++ algorithm matrix

  

可能重复:
  Finding a submatrix with the maximum possible sum in O(n^2)

我有一个NxN矩阵。我想找出上述矩阵的MxM子矩阵,其元素总和最大。

什么是有效的算法。

1 个答案:

答案 0 :(得分:2)

我有一个算法,当放大N时会在恒定时间内运行,而在放大N时会增加二次时间。

第一个子矩阵像往常一样计算。节省金额。然后向右移动一行字段 - 两个MxM矩阵重叠,因此您只需将两个非重叠列相加即可。保存所有金额。现在您可以选择该行的最大金额。

转到下一行。还记得保存的金额吗?第一行和第二行的MxM矩阵再次重叠,因此您可以对MxM矩阵的第一行和最后一行求和,并计算第二行的第一行。

现在转到第二行的第二个总和。做同样的事情,但你发现第一行的最后一行和第二行的第二行重叠。

我知道这有点令人困惑,如果你不明白,请告诉我,我会画出一些照片。该算法基于this answer中的论文。

编辑:我知道我答应了图片,但这应该足够了:

A  AB   AB   AB   AB   B
AC ABCD ABCD ABCD ABCD BD
AC ABCD ABCD ABCD ABCD BD
AC ABCD ABCD ABCD ABCD BD
AC ABCD ABCD ABCD ABCD BD
 C   CD   CD   CD   CD  D

这是四个子类,A,B,C,D,定位如下:

AB
CD

首先计算A子矩阵的总和:sum(A)。这里没有优化。现在你要计算B的总和:总和(B)。您可以像在A中一样,但请注意A和B重叠。因此,您将sum(A)指定给sum(B),计算垂直向量A AC AC AC AC的总和,并从sum(B)中减去if,然后计算垂直向量的总和B BD BD BD BD并将其加到总和中(B)。

sum(B) = sum(A) - sum(A AC AC AC AC) + sum(B BD BD BD BD)

你有总和(B)。现在,您可以继续并计算整个第一行子项。

移动到第二行:matices C和D.您不必对整个matice C求和,因为在前一行中,您保存了sum(A)。注意它们再次重叠。您只需要添加A和C之间的差异:

//code (1)
subC = sum([A AB AB AB AB])   //as substract C
addC = sum([C CD CD CD CD])   //as add C
sum(C) = sum(A) - subC + addC

你有总和(C)。现在你可以得到这样的总和(D):

//code (2)
subD = sum([AB AB AB AB B])    //as substract D
addD = sum([CD CD CD CD D])    //as add D
sum(D) = sum(B) - subD + addD 

但是将subD与subC和addD与addC进行比较。他们重叠!所以你可以这样做:

//code (3)
subD = subC - A + B //from subC substract value on A and add B to it
addD = addC - C + D //same as above
sum(D) = sum(B) - subD + addD

你可以看到,而不是25个用于计算一个子矩阵之和的加法,我们做6.对于MxM的每个可能大小,我们对第一个子矩阵有MxM加法,对第一个行和第一个列有M * 2 + 2个加法其余的6个愿望。

相关问题