最大长方体问题

来源:互联网 发布:淘宝店发货地址 编辑:程序博客网 时间:2024/05/22 03:48
时间限制:1000MS  内存限制:1000K

提交次数: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 30 -1 21 2 21 1 -2-2 -1 -1-3 3 -2-2 -3 1-2 3 30 1 32 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;}