51nod 1051

* 最大子矩阵
* sum[i][j] 表示第 i 行前 j 列的和,即每一行的前缀
* i,j 指针枚举列,k指针枚举行
* Now 记录当前枚举的子矩阵的价值
* 由于记录了前缀信息,一旦 Now < 0, Now = 0
* Max 变量在过程中取最大

#include <bits/stdc++.h>

const int N = 5010;

int sum[N][N];
int n, m;

#define gc getchar()

inline int read() {
    int x = 0, f = 1; char c = gc;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = gc;}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
    return x * f;
}

int main() {
    m = read(), n = read();
    for(int i = 1; i <= n; i ++) {
        for(int j = 1; j <= m; j ++) {
            int x = read();
            sum[i][j] = sum[i][j - 1] + x;
        }
    }
    int Ans(0);
    for(int i = 1; i <= m; i ++) {
        for(int j = i; j <= m; j ++) {
            int Now(0), Max(0);
            for(int k = 1; k <= n; k ++) {
                Now += sum[k][j] - sum[k][i - 1];
                if(Now < 0) Now = 0;
                Max = std:: max(Max, Now);
            }
            Ans = std:: max(Ans, Max);
        }
    }
    printf("%d", Ans);
    
    return 0;
}

 

posted @ 2018-08-08 19:40  xayata  阅读(127)  评论(0编辑  收藏  举报