ZOJ 1074 最大子矩阵和

时间:2025-05-14 21:35:56

Description

Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. 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.  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 corner: 
9 2  -4 1  -1 8  and has a sum of 15. 

Input

The input consists of an N * N array of integers. The input begins with a single positive integer N on a line by itself, indicating the size of the square two-dimensional array. This is followed by N^2 integers separated by whitespace (spaces and newlines). These are the N^2 integers of the array, presented in row-major order. That is, all numbers in the first row, left to right, then all numbers in the second row, left to right, etc. N may be as large as 100. The numbers in the array will be in the range [-127,127].

Output

Output the sum of the maximal sub-rectangle.

Sample Input

4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2

Sample Output

15

题意:求最大的子矩阵的和

解题思路:通过循环,用b[k]数组储存每列的和,例如当循环到第2行时,b[0]储存的就是5。 5是怎么来的呢?它是0+9+(-4)=5。
                                 b[1]储存的就是1。 -2+2+1=1 这样求出每列的和然后同时找b[k]序列的最大子段和,不断更新最大值,循环完之后,就可以找出最大值了..... 也许这样比较抽象,举个栗子:(这里就不用N行N列的做例子了.....) 2维数组:     
         1 2 3
        -5 6 7
     我们先求
          
          第0行   b数组 1 2 3                最大子段和:1+2+3=6  这里可以理解为  这是 1 2 3  这个子矩阵
          
          第1行
                b数组 -4 8 10                最大子段和:8+10=18  这里就是 2 3
                                       6 7  这个子矩阵                 所以答案就是18 怎么说,思想应该是通过求每列的和,使得它变成一个求最大字段和的问题......... 代码如下:(去掉注释,也许会对理解思路有帮助....)
 #include<stdio.h>
#include <limits>
#include<string.h>
using namespace std;
int a[][],b[];
int n,cursum=-,max=numeric_limits<int>::min(); int curmaxsum()
{
int sum=0,cursum=-130;
for(int i=; i<n; i++)
{
sum+=b[i];
if(sum<)
sum=b[i];
if(sum>cursum)
cursum=sum;
}
return cursum;
} int maxsub()
{
for(int i=; i<n; i++)
{
memset(b,,sizeof(b));
for(int j=i; j<n; j++)
{
//printf("\nj=%d\n",j);
for(int k=; k<n; k++)
{
b[k]+=a[j][k];
}
/*for(int k=0; k<n-1; k++)
printf("%d ",b[k]);
printf("%d\n",b[n-1]);*/ curmaxsum();
//printf("cursum=%d\n",cursum);
if(cursum>max)
max=cursum;
// printf("max=%d\n",max);
}
}
return max;
} int main()
{
while(scanf("%d",&n)==)
{
for(int i=; i<n; i++)
for(int j=; j<n; j++)
scanf("%d",&a[i][j]);
// printf("******************************\n\n");
maxsub();
printf("%d\n",max);
}
return ;
}