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;
}