提交次数:950 通过次数:383
题型: 编程题 语言: G++;GCC;VC
Description
一个长,宽,高分别是m,n,p的长方体被分割成m*n*p个小立方体。每个小立方体内含一个整数。 试着设计一个算法,计算所给长方体的最大子长方体。子长方体的大小由它内部所含所有整数之和确定。 约定:当该长方体所有元素均为负数时,输出最大子长方体为0。
输入格式
第一行3个正整数m,n,p,其中 1<=m,n,p<=50 接下来的m*n行中每行p个整数,表示小立方体中的数。
输出格式
第一行中的数是计算出的最大子长方体的大小。
输入样例
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
其实刚开始看到这道题就有思路了,类似于矩形区间求最大矩形和,都是采用矩阵压缩再dp的做法,只不过这道题扩展到了三维,但是
做法还是一样的,话不多说,还是直接上代码吧。
#include <iostream> #include <cstring> #include <cstdio> #define rep(i,n) for(int i=0;i<n;i++) #define mst(a,x) memset(a,x,sizeof(a)) using namespace std; int a[55][55][55]; int b[55][55][55]; int ans[55]; int main() { #ifdef local freopen("in.txt","r",stdin); #endif int n,m,p,res=0; scanf("%d%d%d",&n,&m,&p); mst(b,0); rep(i,n)rep(j,m)rep(k,p) scanf("%d",&a[i][j][k]); rep(i,n)rep(j,m)rep(k,p){ if(j==0&&k==0) b[i][j][k]=a[i][j][k]; else if(k==0) b[i][j][k]=b[i][j-1][k]+a[i][j][k]; else if(j==0) b[i][j][k]=b[i][j][k-1]+a[i][j][k]; else b[i][j][k]=b[i][j-1][k]+b[i][j][k-1]-b[i][j-1][k-1]+a[i][j][k]; } rep(i,n)rep(j,m)rep(k,p){ for(int l=k; l<p; l++){ for(int t=0; t<n; t++){ if(i==0&&k==0) ans[t]=b[t][j][l]; else if(i==0) ans[t]=b[t][j][l]-b[t][j][k-1]; else if(k==0) ans[t]=b[t][j][l]-b[t][i-1][l]; else ans[t]=b[t][j][l]-b[t][i-1][l]-b[t][j][k-1]+b[t][i-1][k-1]; } int sum=0; for(int t=0; t<n; t++){ if(sum>=0){ sum+=ans[t]; if(sum>res) res=sum; }else sum=0; } } } printf("%d\n",res); return 0; }