1146. Maximum Sum
Time limit: 0.5 second
Memory limit: 64 MB
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.
Input
The input consists of an N × N array of integers. The input begins with a single positive integerN on a line by itself indicating the size of the square two dimensional array. This is followed byN 2 integers separated by white-space (newlines and spaces). These N 2 integers make up the array in row-major order (i.e., all numbers on the first row, left-to-right, then all numbers on 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
The output is the sum of the maximal sub-rectangle.
Sample
input | output |
---|---|
4 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 |
15 |
Tags: dynamic programming (hide tags for unsolved problems)
Difficulty: 97
题意:求最大的子矩阵
分析:很经典的题。
知道最大子段和的做法。
然后枚举矩阵的上下界,按照最大子段和的做法做。
1 /** 2 Create By yzx - stupidboy 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cmath> 8 #include <deque> 9 #include <vector> 10 #include <queue> 11 #include <iostream> 12 #include <algorithm> 13 #include <map> 14 #include <set> 15 #include <ctime> 16 #include <iomanip> 17 using namespace std; 18 typedef long long LL; 19 typedef double DB; 20 #define MIT (2147483647) 21 #define INF (1000000001) 22 #define MLL (1000000000000000001LL) 23 #define sz(x) ((int) (x).size()) 24 #define clr(x, y) memset(x, y, sizeof(x)) 25 #define puf push_front 26 #define pub push_back 27 #define pof pop_front 28 #define pob pop_back 29 #define ft first 30 #define sd second 31 #define mk make_pair 32 33 inline int Getint() 34 { 35 int Ret = 0; 36 char Ch = ‘ ‘; 37 bool Flag = 0; 38 while(!(Ch >= ‘0‘ && Ch <= ‘9‘)) 39 { 40 if(Ch == ‘-‘) Flag ^= 1; 41 Ch = getchar(); 42 } 43 while(Ch >= ‘0‘ && Ch <= ‘9‘) 44 { 45 Ret = Ret * 10 + Ch - ‘0‘; 46 Ch = getchar(); 47 } 48 return Flag ? -Ret : Ret; 49 } 50 51 const int N = 110; 52 int n, arr[N][N]; 53 int sum[N][N], p[N]; 54 55 inline void Input() 56 { 57 scanf("%d", &n); 58 for(int i = 1; i <= n; i++) 59 for(int j = 1; j <= n; j++) scanf("%d", &arr[i][j]); 60 } 61 62 inline int Work(int *arr) 63 { 64 int ret = arr[1], cnt = arr[1]; 65 for(int i = 2; i <= n; i++) 66 { 67 if(cnt < 0) cnt = arr[i]; 68 else cnt += arr[i]; 69 ret = max(ret, cnt); 70 } 71 return ret; 72 } 73 74 inline void Solve() 75 { 76 int ans = -INF; 77 for(int i = 1; i <= n; i++) 78 for(int j = 1; j <= n; j++) 79 sum[i][j] = sum[i - 1][j] + arr[i][j]; 80 for(int i = 1; i <= n; i++) 81 for(int j = i; j <= n; j++) 82 { 83 for(int k = 1; k <= n; k++) 84 p[k] = sum[j][k] - sum[i - 1][k]; 85 int cnt = Work(p); 86 /*if(ans < cnt) 87 { 88 ans = cnt; 89 printf("%d %d %d\n", ans, i, j); 90 }*/ 91 ans = max(ans, cnt); 92 } 93 94 cout << ans << endl; 95 } 96 97 int main() 98 { 99 freopen("a.in", "r", stdin); 100 Input(); 101 Solve(); 102 return 0; 103 }