题意:求最大子矩阵和。
将此问题转化为求多个最大子段和(行)的问题即可。
如:先求出第一行(a[0])的最大子字和,再将第二行a[1]的所有元素分别加到a[0]上去,再计算a[0]的最大子段和。
枚举所有起点行和终点行,得到的最大值即为答案。O(n^3),AC / 16MS。
//poj 1050 - dp
//2014-6-11
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX_N = 111;
int n;
int a[MAX_N][MAX_N];
//int d[MAX_N][MAX_N][MAX_N];
int inline getMax ( int a, int b, int c )
{
return max ( a, max ( b, c ) );
}
int d[MAX_N][MAX_N];
void dp()
{
memset ( d, 0, sizeof ( d ) );
//answer
int Max = -128;
//calculate the max sum of sub-matrix(sub-segment) of line i to j
//i-th line
for ( int i = 0; i < n; i++ )
{
//j-th line
for ( int j = i; j < n; j++ )
{
int b = 0;
//k-th cow
for ( int k = 0; k < n; k++ )
{
//add the j-th line element to the i-th line
if ( j > i )
{
a[i][k] += a[j][k];
}
//calculate the max sum of sub-segment.
if ( b > 0 )
{
b += a[i][k];
}
else
{
b = a[i][k];
}
Max = max ( Max, b );
}
}
}
printf ( "%d\n", Max );
}
int main()
{
freopen ( "in.txt", "r", stdin );
scanf ( "%d", &n );
for ( int i = 0; i < n; i++ )
{
for ( int j = 0; j < n; j++ )
{
scanf ( "%d", &a[i][j] );
}
}
dp();
return 0;
}