Given a 2-dimensional array of positive and negative integers, find the sub-rectangle with the largest sum. The sum of a rectangle is the sum of all the elements in that rectangle. In this problem the sub-rectangle with the largest
sum is referred to as the maximal sub-rectangle. A sub-rectangle is any contiguous sub-array of size 1 × 1 or greater located within the whole array.
As an example, the maximal sub-rectangle of the array:
| 0 | −2 | −7 | 0 |
| 9 | 2 | −6 | 2 |
| −4 | 1 | −4 | 1 |
| −1 | 8 | 0 | −2 |
is in the lower-left-hand corner and has the sum of 15.
‘
题目要求对已给矩阵求出其中最大子矩阵
这道题目一开始不知到怎么入手,一开始想能否从做以一个点为顶点求其各种可能的子矩阵。
然而并没有什么卵用 然而并没有什么卵用 然而并没有什么卵用 重要的事情说三遍
这种很直观的作法显然不算dp 而且遍历矩阵中每一个点已经是n^2 再求子矩阵,妥妥的再见;
于是乎,为了简便 先对矩阵进行处理
就是对矩阵的每一列 求前缀和 这样求指定的两个行之间的列元素之和就是一个减法了。
然而这样之后原来的想法的 还是然并卵。
故尝试了其他的想法 ,就是先对行进行枚举, 由于可以枚举两个行数是n^2 ,再对列枚举 由于列要连续,是n。
所以总的复杂度是n^3 在对细节处理下 就A了的说。。。。。。。
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int map1[110][110];
int sum[110][110];
int n;
void init()
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
scanf("%d",&map1[i][j]);
}
for(int i = 0; i <= n; i++) sum[0][i] = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
sum[i][j] = sum[i-1][j] + map1[i][j];
}
}
return ;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
int ans = -2000000,t = 0;
for(int i = 1; i <= n; i++)
{
for(int j = i; j <= n; j++)
{
t = 0;
for(int k = 1; k <= n; k++)
{
t += sum[j][k] - sum[i-1][k];
ans = max(ans,t);
if(t < 0)
t = 0;
}
}
}
printf("%d\n",ans);
}
return 0;
}
本文介绍了一种寻找二维数组中最大子矩阵和的有效算法。通过对矩阵的每一列预计算前缀和,使得后续查找任意两行间列元素之和的操作简化为一次减法运算。在此基础上,通过枚举矩阵中的行区间,结合 Kadane 算法在一维数组中寻找最大子数组和的方法,最终实现 O(n^3) 复杂度内解决问题。
392

被折叠的 条评论
为什么被折叠?



