这个题的大意是说给你一个矩阵,这个矩阵特殊的是上下左右是连通的,也就是说第一排的上面一排是最后一排,第一列的上一列是最后一列,要求你求出一个和最大的子矩阵。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int map[200][200],sum[200][200],dp[200];
int main()
{
int n,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
map[i][j+n]=map[i][j];
map[i+n][j]=map[i+n][j+n]=map[i][j];
}
memset(sum,0,sizeof(sum));
for(int i=1;i<=2*n;i++)
for(int j=1;j<=2*n;j++)
sum[i][j]=sum[i-1][j]+map[i][j];
int ans=-100000010;
for(int i=0;i<=n;i++)
for(int j=i+1;j<=i+n;j++)
{
memset(dp,0,sizeof(dp));
int pre=1,suma=0;
for(int k=1;k<=2*n;k++)
{
int ita=sum[j][k]-sum[i][k];
dp[k]=dp[k-1]+ita;
if(k-pre>=n)
{
suma=suma-(dp[pre]-dp[pre-1]);
pre++;
for(int l=pre;l<=k;l++)
{
if(dp[pre]<=0)
{
suma=suma-(dp[pre]-dp[pre-1]);
pre++;
}
else if(dp[l]-dp[pre-1]<=0)
{
suma=suma-(dp[l]-dp[pre-1]);
pre=l+1;
}
}
}
if(suma<=0)
{
suma=ita;
ans=max(suma,ans);
pre=k;
}
else
{
suma+=ita;
ans=max(suma,ans);
}
}
}
printf("%d\n",ans);
}
return 0;
}