最大长方体问题

时间限制: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 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;
}


 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值