UVA 10755 Garbage Heap 三维最大子矩阵和 -

题目地址:http://vjudge.net/problem/UVA-10755

像基础的一维,二维,根据前缀和能求出所有的体积,在得到后直接枚举就好了

#include <bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=a;i<=(b);++i)
#define REPD(i,a,b) for(int i=a;i>=(b);--i)
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
typedef long long LL;
const LL maxn=20+3,INF=(1LL<<60);
LL n,S[maxn][maxn][maxn]; //S[i][j][k] 记录(1,1,1)->(i,j,k)的体积
void Expend(int i,int& a,int& b,int& c){
	a=i&1; i>>=1;
	b=i&1; i>>=1;
	c=i&1;
}
int inline sign(int a,int b,int c){
	return (a+b+c)&1?1:-1;  //符号为什么这么变 ,画个图就知道了
}
LL sum(int x1,int x2,int y1,int y2,int z1,int z2){
	int dx=x2-x1+1,dy=y2-y1+1,dz=z2-z1+1;
	LL s=S[x2][y2][z2];
	REP(i,1,7){
		int a,b,c;
		Expend(i,a,b,c);
		s-=S[x2-a*dx][y2-b*dy][z2-c*dz]*sign(a,b,c);
	}
	return s;
}
int main(int argc, char const *argv[])
{
	int T,x0,y0,z0,a,b,c; scanf("%d",&T);
	while(T--){
		scanf("%d%d%d",&a,&b,&c);
		memset(S,0,sizeof(S));
		REP(i,1,a) REP(j,1,b) REP(k,1,c) {
			scanf("%lld",&S[i][j][k]);
			REP(l,1,7){
				Expend(l,x0,y0,z0);
				S[i][j][k]+=S[i-x0][j-y0][k-z0]*sign(x0,y0,z0); //递推出S[i][j][k]
			}
		}
		
		LL ans=-INF;
		REP(x1,1,a) REP(x2,x1,a) REP(y1,1,b) REP(y2,y1,b){ //固定住x,y, 
			LL M=0;    
			REP(z,1,c){   //求出在此范围内 最大和
				LL Sum=sum(x1,x2,y1,y2,1,z);
				ans=max(ans,Sum-M);
				M=min(M,Sum);   //用M保存最小,可以免得枚举z1~z2
			}
		}
		printf("%lld\n", ans);
		if(T) putchar('\n');
	}
	return 0;
		
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值