题目链接:最大子矩阵和
题目描述当所有数都为负数时输出0,意味着除了都为0的情况,总存在一个数>=0,即结果一定>=0,所以当中间结果tmp<0时,后面加它都必然使得结果更小,意味着上面的段不用,tmp置为0,从下一段重新开始寻找可能的最大值。转化为最大子段和求解。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#include<map>
#include<set>
#include<cstdlib>
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long ll;
using namespace std;
const int maxn = 510;
int x,y;
ll dp[maxn][maxn],num;
int main(){
ll ans;
while(scanf("%d%d",&x,&y) != EOF){
mem(dp,0);
for(int i = 1; i <= y; i++){
for(int j = 1; j <= x; j++){
scanf("%lld",&num);
dp[i][j] = dp[i-1][j] + num;
}
}
ans = 0;
ll tmp;
for(int i = 1; i <= y; i++){
for(int j = i; j <= y; j++){
tmp = 0;
for(int k = 1; k <= x; k++){
tmp += dp[j][k] - dp[i-1][k];
if(tmp < 0) tmp = 0;
if(tmp > ans) ans = tmp;
}
}
}
printf("%lld\n",ans);
}
return 0;
}