To the Max
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 27900 | Accepted: 14460 |
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
题目大意就是给出一个n×n的矩阵,要求在里面找一个子矩阵,使得子矩阵中的元素和是最大的,输出这个最大的元素和
例如对于题目中的矩阵
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
则可以找到子矩阵
9 2
-4 1
-1 8
其所有元素和为15 是最大的子矩阵
故输出为15
解决这题首先要会求
给n个数,问这n个数的最大子串和是多少?
这一道题就是把上面的问题拓展到了二维,但解决方法类似
枚举所有的行组合,将这些行压缩成一个数列,进行上述操作就可以了
例如对于矩阵
1 2 3 4
2 3 4 1
2 3 1 4
将第一行和第二行压缩结果为3 5 7 5
同理,将第二行第三行压缩结果为4 6 5 5
将一二三行压缩结果为5 8 8 9
•想一想,如果三维呢?三维无非就压缩两次嘛……
刚开始时有个细节没注意到,WA了一次
参考代码:
1 1#include<iostream>
2 #include<cstdlib>
3 #include<cstdio>
4 #include<cstring>
5 #include<algorithm>
6 #include<cmath>
7 using namespace std;
8 int a[105][105];
9 int sum[105];
10 int dp[105];
11 int main()
12 {
13 int n ;
14 while ( cin >> n )
15 {
16 int i , j , k , t;
17 for ( i = 0 ; i < n ; i ++ )
18 for ( j = 0 ; j < n ; j ++ )
19 cin >> a[i][j] ;
20 int sumall = - (1 << 30 );
21 for ( i = 0 ; i < n ; i ++ )
22 {
23 int sumdp;
24 for ( t = i + 1 ; t <= n ; t ++ )
25 {
26 for ( j = 0 ; j < n ; j ++ )
27 {
28 int sumi = 0 ;
29 for ( k = i ; k < t ; k ++ )
30 {
31 sumi += a[k][j] ;
32 }
33 sum[j] = sumi ;
34 if ( j )
35 sumall = max ( sumall , sumdp = max ( sumdp + sum[j] , sum[j] ) ) ;
36 else
37 sumall = max ( sumall , sumdp = sum[j] ) ;
38 }
39 }
40 }
41 cout << sumall << endl ;
42 }
43 return 0 ;
44 }