题目描述:已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵。
样例
输入:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
输出:
9 2
-4 1
-1 8
方法一:
利用二维数组的前缀和数组f来预处理a【1】【1】~a【i】【j】的和
即在每次输入数据后加上f[i][j]=f[i][j-1]+f[i-1][j]-f[i-1][j-1]+a[i][j];
用双重for循环,再用双重for循环,最后再利用前缀和数组:f[x][y]-f[i-1][y]-f[x][j-1]+f[i-1][j-1];求出该子矩阵的和,并最后与ans比较:
代码如下:
ans=a[1][1];for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
for(x=i;x<=n;x++)
for(y=j;y<=m;y++)
s=f[×][y]-f[i-1][y]-f[×][j-1]+f[i-1][j-1];if(s>ans)
ans=s;
该程序的复杂度约为n^4.
f[i][j]=f[i][j-1]+f[i-1][j]-f[i-1][j-1]+a[i][j]的推导:
(下一页)
求f[i][j]可以先将f[1][1]~f[i-1][j]的所有数字和跟f[1][1]~f[i][j-1]的所有数字和加起来,后发现多加了f[1][1]~f[i-1][j-1]这一部分,于是减掉再加上新输入的a[i][j]即可利用递推法求出f[i][j]=f[i][j-1]+f[i-1][j]-f[i-1][j-1]+a[i][j]
f[x][y]-f[i-1][y]-f[x][j-1]+f[i-1][j-1]的推导:
一样的思路,想要求a[i][j]~a[x][y]的和,需要用f[x][y]的值减去一部分的和,即减去f[x][j-1]和f[i-1][y]的值,发现多减去了f[i-1][j-1]的值,加上即可求出f[x][y]-f[i-1][y]-f[x][j-1]+f[i-1][j-1]
方法二:
将i首,将j尾,然后枚举结尾:j的循环就是i到n个循环。行数就是i到m,列数就是j到n,在这个范围里随意一个数都是它的结尾,最后去求和。
代码如下:
(下一页)
复杂度约为n^6