长方体中求价值最大的子长方体。由于之前做过一维和二维的所以这个相对来说比较好想。枚举高的上下界,用时O(n^2),这样问题就转化为二维长求最大子矩形,这个问题可以使用前缀和+DP在O(n^3)内解决。时间复杂度为O(n^5)。注意题中每个价值范围在正负2^31之内,所以求最大值,ans初值应该取最小,则至少应该取负2^31。另外注意每个样例之间有个空行。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define inf -2139062144
#define MOD 20071027
#define MAXN 25
using namespace std;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int A,B,C;
scanf("%d%d%d",&A,&B,&C);
ll grid[MAXN][MAXN][MAXN]= {0};
for(int i=1; i<=A; ++i)
for(int j=1; j<=B; ++j)
for(int k=1; k<=C; ++k)
scanf("%lld",&grid[i][j][k]);
ll up[MAXN][MAXN][MAXN]= {0},sum[MAXN][MAXN][MAXN]= {0};
for(int i=1; i<=A; ++i)
for(int j=1; j<=B; ++j)
for(int k=1; k<=C; ++k)
up[i][j][k]=up[i-1][j][k]+grid[i][j][k];
ll ans=-2147483648LL;
for(int i=1; i<=A; ++i)
for(int j=i; j<=A; ++j)
{
ll sum[MAXN][MAXN]= {0};
for(int p=1; p<=B; ++p)
for(int q=1; q<=C; ++q)
sum[p][q]=sum[p][q-1]+(up[j][p][q]-up[i-1][p][q]);
for(int p=1; p<=C; ++p)
for(int q=p; q<=C; ++q)
{
ll res=0;
for(int k=1; k<=B; ++k)
{
ll val=sum[k][q]-sum[k][p-1];
if(res<0) res=val;
else res+=val;
ans=max(res,ans);
}
}
}
printf("%lld\n",ans);
if(T) printf("\n");
}
return 0;
}