挺不错的dp基础题,值得反复思考。
这道题是由一维序列的最大连续子序和(HDU1003)延伸而来,而一维的解法是:
如果当前的子序和小于0,那么把它置为0;
如果当前的子序和大于之前的最大值,那么更新最大值。
二维的情况,我们可以枚举矩形的上边,往两个方向延伸,每个方向都如一维般解。
POJ和HOJ的数据没有出现全负的情况,但我们还是要精益求精的。
#include <iostream>
#include <string.h>
using namespace std;
int s[105];
int cal(int n){
int sum = 0, res = 0;
for(int i = 0; i < n; i++){
sum += s[i];
if(sum < 0) sum = 0;
if(sum > res) res = sum;
}
return res;
}
int main()
{
int n, cnt = -128;
int a[105][105];
cin >> n;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
cin >> a[i][j];
if(a[i][j] > cnt)
cnt = a[i][j];
}
}
int res = 0;
for(int i = 0; i < n; i++){
memset(s, 0, sizeof(s));
for(int j = i; j < n; j++){
for(int k = 0; k < n; k++)
s[k] += a[j][k];
res = max(res, cal(n));
}
}
if(!res) res = cnt;
cout << res << endl;
return 0;
}