这道题是求最大子矩阵和的加强版,原矩阵是一个上下左右都可以串通的矩阵环,原方法是将原矩阵复制为四个,然后依次以n*n的矩阵为原型照搬最大子矩阵和的DP,但其复杂度为O(n5),交上后TLE,修改了若干变不是WA,就是TLE,最后,参考了结题报告,复制完矩阵后,
枚举所求最大子矩阵在第一个矩阵中的左上角,再通过动态规划的方法求出长宽不大于N的最大子矩阵,各种枚举情况中的最大和即为所求解。
代码如下:
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
using namespace std;
int a[200][200],b[200],c[200];
int main()
{
#ifdef test
freopen("in.txt", "r", stdin);
#endif
int i,j,t,n,x,y,ans;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
scanf("%d",&a[i][j]);
a[i+n][j] = a[i][j+n] = a[i+n][j+n] = a[i][j];
}
ans = -0x7FFFFFFF;
for(x=0; x<n; x++)
for(y=0; y<n; y++)
for(j=0; j<n; j++)
for(i=0; i<n; i++)
{
c[i]=a[i+x][j+y];
if(i)
c[i] += c[i-1];
if(j)
b[i] += c[i];
else
b[i] = c[i];
if(b[i] > ans)
ans = b[i];
}
printf("%d\n",ans);
}
return 0;
}