传送门
题目大意:给出一个n*m的矩阵,选出3个不相交的k*k的矩阵,使权值和最大。
mx(i,j,1/2/3/4)表示左上/右上/左下/右下端点在(i,j)范围内的最大的矩形
ver/hor(i,j)表示横/竖在[i,j]范围内的最大的矩形(只有(1,i)(i,n)是所有的)
然后暴力枚举横竖切的划分、拆分成3份的划分即可
时间 O(n2)
#include
#include
#include
#include
#include
using namespace std;
#define N 1505
int n,m,k,ans;
int a[N][N],s[N][N],mx[N][N][5],ver[N][N],hor[N][N];
int main()
{
scanf("%d%d%d",&n,&m,&k);
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j) scanf("%d",&a[i][j]);
for (int i=1;i<=m;++i)
for (int j=1;j<=n;++j) s[j][i]=s[j-1][i]+a[j][i];
for (int i=1;i<=n-k+1;++i)
{
int now=0;
for (int j=1;j<=k;++j) now+=s[i+k-1][j]-s[i-1][j];
mx[i][1][1]=mx[i][k][2]=mx[i+k-1][1][3]=mx[i+k-1][k][4]=now;
ver[1][k]=max(ver[1][k],now);hor[i][i+k-1]=max(hor[i][i+k-1],now);
for (int j=2;j<=m-k+1;++j)
{
now-=s[i+k-1][j-1]-s[i-1][j-1];
now+=s[i+k-1][j+k-1]-s[i-1][j+k-1];
mx[i][j][1]=mx[i][j+k-1][2]=mx[i+k-1][j][3]=mx[i+k-1][j+k-1][4]=now;
ver[j][j+k-1]=max(ver[j][j+k-1],now);hor[i][i+k-1]=max(hor[i][i+k-1],now);
}
}
for (int i=1;i<=n;++i)
{
for (int j=m;j>=1;--j)
mx[i][j][3]=max(mx[i][j][3],max(mx[i-1][j][3],mx[i][j+1][3]));
for (int j=1;j<=m;++j)
mx[i][j][4]=max(mx[i][j][4],max(mx[i-1][j][4],mx[i][j-1][4]));
}
for (int i=n;i>=1;--i)
{
for (int j=m;j>=1;--j)
mx[i][j][1]=max(mx[i][j][1],max(mx[i+1][j][1],mx[i][j+1][1]));
for (int j=1;j<=m;++j)
mx[i][j][2]=max(mx[i][j][2],max(mx[i+1][j][2],mx[i][j-1][2]));
}
for (int i=1;i<=n;++i)
{
hor[1][i]=max(hor[1][i],hor[1][i-1]);
for (int j=1;j<=i;++j) hor[1][i]=max(hor[1][i],hor[j][i]);
}
for (int i=n;i>=1;--i)
{
hor[i][n]=max(hor[i][n],hor[i+1][n]);
for (int j=n;j>=i;--j) hor[i][n]=max(hor[i][n],hor[i][j]);
}
for (int i=1;i<=m;++i)
{
ver[1][i]=max(ver[1][i],ver[1][i-1]);
for (int j=1;j<=i;++j) ver[1][i]=max(ver[1][i],ver[j][i]);
}
for (int i=m;i>=1;--i)
{
ver[i][m]=max(ver[i][m],ver[i+1][m]);
for (int j=m;j>=i;--j) ver[i][m]=max(ver[i][m],ver[i][j]);
}
for (int i=1;i<=n-k+1;++i) ans=max(ans,hor[1][i-1]+hor[i][i+k-1]+hor[i+k][n]);
for (int i=1;i<=m-k+1;++i) ans=max(ans,ver[1][i-1]+ver[i][i+k-1]+ver[i+k][m]);
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
{
ans=max(ans,mx[1][j][1]+mx[i-1][j-1][4]+mx[i][j-1][2]);
ans=max(ans,mx[1][j][1]+mx[i][j-1][4]+mx[i+1][j-1][2]);
ans=max(ans,mx[1][j-1][2]+mx[i-1][j][3]+mx[i][j][1]);
ans=max(ans,mx[1][j-1][2]+mx[i][j][3]+mx[i+1][j][1]);
ans=max(ans,mx[1][j+1][1]+mx[i-1][j][4]+mx[i][j][2]);
ans=max(ans,mx[1][j+1][1]+mx[i][j][4]+mx[i+1][j][2]);
ans=max(ans,mx[1][j][2]+mx[i-1][j+1][3]+mx[i][j+1][1]);
ans=max(ans,mx[1][j][2]+mx[i][j+1][3]+mx[i+1][j+1][1]);
ans=max(ans,mx[i][1][1]+mx[i-1][j-1][4]+mx[i-1][j][3]);
ans=max(ans,mx[i][1][1]+mx[i-1][j-1][4]+mx[i-1][j+1][3]);
ans=max(ans,mx[i-1][1][3]+mx[i][j-1][2]+mx[i][j][1]);
ans=max(ans,mx[i-1][1][3]+mx[i][j][2]+mx[i][j+1][1]);
ans=max(ans,mx[i+1][1][1]+mx[i][j-1][4]+mx[i][j][3]);
ans=max(ans,mx[i+1][1][1]+mx[i][j][4]+mx[i][j+1][3]);
ans=max(ans,mx[i][1][3]+mx[i+1][j-1][2]+mx[i+1][j][1]);
ans=max(ans,mx[i][1][3]+mx[i+1][j][2]+mx[i+1][j+1][1]);
}
printf("%d\n",ans);
}