问题描述:
一个长、宽、高分别为m,n,p的长方体被分割成m*n*p个小立方体。每个小立方体内有一个整数,设汁一个算法,计算出所给长方体的最大子长方体。子长方体的大小由它所含的所有整数之和确定。
代码展示:
#include "iostream"
using namespace std;const int maxn=20;//定义常量指定数组的大小
/*动态规划:
d[0]=c[0];
当i>0时,d[i]=max{d[i-1]+c[i],c[i]},
其中d[i]表示数组c前(i+1)个元素的最大子段和*/
int maxSum1D(int c[],int p)//求一维数组的最大子段和
{
int sum=0,d=0;
for(int i=0;i<p;i++)
{
if(d>0)
d=d+c[i];
else
d=c[i];
if(sum<d)
sum=d;
}
return sum;
}
/*求出最大一面子墙的和*/
int maxSum2D(int b[][maxn],int n,int p)//求二维矩阵的最大子矩阵和
{
int c[maxn];
int max,sum=0;
for(int i=0;i<n;i++)
{
for(int tempk=0;tempk<p;tempk++)
c[tempk]=0;
for(int j=i;j<n;j++){
for(int k=0;k<p;k++)
c[k]+=b[j][k];
max=maxSum1D(c,p);
if(max>sum) sum=max;
}
}
return sum;
}
/*将数组a想象成一面面的墙,共有m面墙,墙宽n,高p
从第i面墙开始,依次选择相邻的0(即只有自身一面墙),1,2,3,4直到第m-1面墙,
其中i为0,1,2,3,4...,m-1*/
int maxSum3D(int a[][maxn][maxn],int m,int n,int p)//求出三维矩阵的最大长方体
{
int b[maxn][maxn];
int max,sum=0;
for(int i=0;i<m;i++)
{
for(int tempn=0;tempn<n;tempn++)
for(int tempk=0;tempk<p;tempk++)
b[tempn][tempk]=0;
for(int j=i;j<m;j++)
{
for(int k=0;k<n;k++)
{
for(int l=0;l<p;l++)
{
b[k][l]+=a[j][k][l];
}
}//该双重循环用于将选择的墙的压缩为一面墙,即成为二维数组
max=maxSum2D(b,n,p);
if(max>sum) sum=max;
}
}
return sum;
}
int main(int argc, char* argv[])
{
int a[maxn][maxn][maxn];
int m,n,p;
cin>>m>>n>>p;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
for(int k=0;k<p;k++)
cin>>a[i][j][k];
cout<<maxSum3D(a,m,n,p)<<endl;
return 0;
}
输入测试:
3 3 3
0 -1 2
1 2 2
1 1 -2
-2 -1 -1
-3 3 -2
-2 -3 1
-2 3 3
0 1 3
2 1 -3
输出结果:
14