http://acm.nyist.net/JudgeOnline/problem.php?pid=104
#include <stdio.h>
#include <memory.h>
#define M 110 //(i,j)看成常数后 枚举i,j
int w[M][M],dp[M];// dp[k] 从第i行到第j行 以第k列结尾的最大子矩阵
int main()
{
int t,r,c,i,j,k,a[M][M],max;
scanf("%d",&t);
while(t--)
{
max=-1;
memset(w,0,sizeof(w));
scanf("%d%d",&r,&c);
for(i=1;i<=r;i++)
{
for(j=1;j<=c;j++)
{
scanf("%d",&a[i][j]);
}
}
for(j=1;j<=c;j++)
{
for(i=1;i<=r;i++)
{
w[j][i]=w[j][i-1]+a[i][j]; //w[j][i] 第j列的前i个数
}
}
// 一维中最后一个元素 - > 二维中从 i行到j行 以第k列结尾的累加和
for(i=1;i<=r;i++)
{
for(j=i;j<=r;j++) // 从第i行到第j行
{ // dp[k]只与当前的 i,j 有关 所以求完一组 i,j的dp[k]的值时可以不用保存
for(k=1;k<=c;k++)//前k列
{
if(k==1)
{
dp[k]=w[k][j]-w[k][i-1];
}
else
{
if(dp[k-1]>=0)
{
dp[k]=dp[k-1]+w[k][j]-w[k][i-1];
}
else
{
dp[k]=w[k][j]-w[k][i-1];
}
}
if(max<dp[k])
max=dp[k];
}
}
}
printf("%d\n",max);
}
return 0;
}