注解
1、类似于hdu_1003的最大连续子序列,区别是:本题是二维的,题目要求找到一个矩阵当中的最大的子矩阵。
2、本题需要把二维压缩到一维。具体做法是,每列相加,相加的和当作一维的一个元素。(看下面代码的两个内层循环)另一个问题是如何遍历二维矩阵的所有子矩阵?(看下面代码的最外层循环)。关键代码如下:
for(int i=0; i<N; i++){
int b[N];
memset(b, 0, sizeof(b));
for(int j=i; j<N; j++){
for(int k=0; k<N; k++){
b[k] += a[j][k];
}
ans = max(ans, dp(b, N));
}
}
3、注意ans的初始值。题目说元素都在[-127,127]范围,因此最小值应该初始化为-128,才能保证合理。否则可能出现全为负数的情况(但题目的测试案例好像不涉及此情况)
代码
#include <iostream>
#include <cstring>
using namespace std;
int dp(int b[], int N){
int tmp = b[0];
int ans = b[0];
for(int i=1; i<N; i++){
tmp = max(tmp+b[i], b[i]);
ans = max(ans, tmp);
}
return ans;
}
int main() {
int N;
while(cin>>N){
int a[N][N];
for(int i=0; i<N; i++){
for(int j=0; j<N; j++){
cin>>a[i][j];
}
}
int ans = -128;
for(int i=0; i<N; i++){
int b[N];
memset(b, 0, sizeof(b));
for(int j=i; j<N; j++){
for(int k=0; k<N; k++){
b[k] += a[j][k];
}
ans = max(ans, dp(b, N));
}
}
cout<<ans<<endl;
}
return 0;
}