POJ1050To the Max

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

题目的大意就是说在给出的n*n个数组成的矩形中饭找出一个小矩形,使得这些数的和最大。
这道题可以借鉴求最大和的连续子序列的方法来做;
在i,j行之间求出每一列这之间的和,那么这个和的最大连续子序列和就是所求
如样例:
0 -2 -7 0

9 2 -6 2
-4 1 -4 1
-1 8 0 -2
假如在第一行到第三行之间求每一列的和那就是
-13 1 -17 3
这个序列的最大连续区间的和就是举行的高为1-3行之间的最大矩形里的和
那么我们就只需要枚举所有行的区间就行了,连续区间最大和的球阀复杂度是O(n),枚举所有行是O(n^2),所以总的复杂度就是O(n^3)。n<=100所以不会超时
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #define MAX(a,b) (a) > (b)? (a):(b)
 6 #define MIN(a,b) (a) < (b)? (a):(b)
 7 #define mem(a) memset(a,0,sizeof(a))
 8 #define INF 1000000007
 9 #define MAXN 105
10 #define MAXC 1005
11 using namespace std;
12 
13 int N,ma[105][105];
14 int sumU[105][105],sum[105];
15 int main()
16 {
17     while(~scanf("%d",&N))
18     {
19         mem(sumU);
20         int i,j,ans = -INF;
21         for(i=1;i<=N;i++)for(j=1;j<=N;j++)
22         {
23             scanf("%d",&ma[i][j]);
24             sumU[i][j]=sumU[i-1][j]+ma[i][j];
25         }
26         int Top,Down;
27         for(Top=0;Top<N;Top++)
28         {
29             for(Down=Top+1;Down<=N;Down++)
30             {
31                 mem(sum);
32                 int min, max = -INF;
33                 min = sumU[Down][1]-sumU[Top][1];//(sumU[Down][1]-sumU[Top][1])>0?0:(sumU[Down][1]-sumU[Top][1]);
34                 for(i=2;i<=N;i++)
35                 {
36                     if(min<0)min=(sumU[Down][i]-sumU[Top][i]);
37                     else min+=(sumU[Down][i]-sumU[Top][i]);
38                     if(max<min)max=min;
39                 }
40                 ans=MAX(ans,max);
41             }
42         }
43         printf("%d\n",ans);
44     }
45     return 0;
46 }

 

posted @ 2013-05-30 22:18  再见~雨泉  阅读(274)  评论(0编辑  收藏  举报