Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 41297 | Accepted: 21905 |
Description
Input
Output
Sample Input
4
0 -2 -7 0 9 2 -6 2
-4 1 -4 1 -1
8 0 -2
Sample Output
15
Source
#include <cstdio> #include <cstring> int const MAX = 101; int const MIN = -2147483647; int MaxSum1(int *a, int len) //求最大子段的函数 { int ma = MIN, cur = 0; //因为要考虑全为负数的情况,故将max初始化为最小值; for(int i = 1; i <= len; i++) { cur += a[i]; //让cur累加数组中的数,cur为当前的子序列和,如果cur大于max,则赋值, if(cur > ma) //若cur小于零,则将cur置零,因为再加后面的数必然不是最大的结果, ma = cur; if(cur < 0) cur = 0; } return ma; } int MaxSum2(int n, int a[][101]) //求最大子矩阵的函数 { int ma = MIN; int *b = new int [n + 1]; //动态分配数组b的内存,长度为n,这里数组b用来一维化二维矩阵 for(int i = 1; i <= n; i++) { for(int k = 1; k <= n; k++) //初始化数组b,这里不能用memset,因为是从1-n b[k] = 0; for(int j = i; j <= n; j++) //枚举从第i行开始的所有行的组合 (这里不用考虑列,因为列的最优解将通过MaxSum1()函数得到) { for(int k = 1; k <= n; k++) b[k] += a[j][k]; int cur = MaxSum1(b,n); //将每种行的组合得到的最优解赋给cur if(cur > ma) //若cur > max则赋值 ma = cur; } } delete []b; return ma; } int main() { int n, num[MAX][MAX]; scanf("%d", &n); for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) scanf("%d", &num[i][j]); printf("%d\n", MaxSum2(n, num)); }