题目地址:http://poj.org/problem?id=1050
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.
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
时间复杂度为O(N^2*M^2)
#include <stdio.h> #include <limits.h> //PS[i][j]等于以(1, 1), (1, j), (i, 1), (i, j)为顶点的矩形区域的元素之和 void Preproccess(int matrix[101][101], int PS[101][101], int N){ int i, j; for (i=0; i<=N; ++i){ PS[0][i] = 0; PS[i][0] = 0; } for (i=1; i<=N; ++i){ for (j=1; j<=N; ++j){ PS[i][j] = PS[i-1][j] + PS[i][j-1] - PS[i-1][j-1] + matrix[i][j]; } } } int main(void){ int N; int matrix[101][101]; int PS[101][101]; int i, j; int i_min, i_max; int j_min, j_max; int max, tmp; while (scanf ("%d", &N) != EOF){ for (i=1; i<=N; ++i) for (j=1; j<=N; ++j) scanf ("%d", &matrix[i][j]); Preproccess(matrix, PS, N); max = INT_MIN; /*以(i_min, j_min), (i_max, j_min), (i_min, j_max), (i_max, j_max)为顶点的矩形区域的元素之和, 等于PS[i_max][j_max] - PS[i_min-1][j_max] - PS[i_max][j_min-1] + PS[i_min-1][j_min-1] */ for (i_min=1; i_min<=N; ++i_min){ for (i_max=i_min; i_max<=N; ++i_max){ for (j_min=1; j_min<=N; ++j_min){ for (j_max=j_min; j_max<=N; ++j_max){ tmp = PS[i_max][j_max] - PS[i_min-1][j_max] - PS[i_max][j_min-1] + PS[i_min-1][j_min-1]; if (tmp > max) max = tmp; } } } } printf ("%d ", max); } return 0; }
时间复杂度为O(N*M*min(N, M))
#include <stdio.h> #include <limits.h> //PS[i][j]等于以(1, 1), (1, j), (i, 1), (i, j)为顶点的矩形区域的元素之和 void Preproccess(int matrix[101][101], int PS[101][101], int N){ int i, j; for (i=0; i<=N; ++i){ PS[0][i] = 0; PS[i][0] = 0; } for (i=1; i<=N; ++i){ for (j=1; j<=N; ++j){ PS[i][j] = PS[i-1][j] + PS[i][j-1] - PS[i-1][j-1] + matrix[i][j]; } } } //BC(PS, a, c, i)表示在第a行和第c行之间的第i列的所有元素的和,可以通过“部分和”PS[i][j]在O(1)时间内计算出来。 int BC(int PS[101][101], int a, int c, int i){ return PS[c][i] - PS[a-1][i] - PS[c][i-1] + PS[a-1][i-1]; } int MaxSum (int matrix[101][101], int PS[101][101], int N){ int max = INT_MIN; int a, c, i; int Start, All; for (a=1; a<=N; ++a){ for (c=a; c<=N; ++c){ Start = BC(PS, a, c, N); All = BC(PS, a, c, N); for (i=N-1; i>=1; --i){ if (Start < 0) Start = 0; Start += BC(PS, a, c, i); if (Start > All) All = Start; } if (All > max) max = All; } } return max; } int main(void){ int N; int matrix[101][101]; int PS[101][101]; int i, j; while (scanf ("%d", &N) != EOF){ for (i=1; i<=N; ++i) for (j=1; j<=N; ++j) scanf ("%d", &matrix[i][j]); Preproccess(matrix, PS, N); printf ("%d ", MaxSum (matrix, PS, N)); } return 0; }
HDOJ上相似的题目:http://acm.hdu.edu.cn/showproblem.php?pid=1559
九度OJ上相似的题目:http://ac.jobdu.com/problem.php?pid=1492
参考资料:编程之美