uva10755 - Garbage Heap 找最大子立方体

来源:互联网 发布:js 替换某一标签 编辑:程序博客网 时间:2024/04/28 06:23

Garbage Heap

Time limit: ? seconds
Memory limit: 64 megabytes

Farmer John has a heap of garbage formed in a rectangular parallelepiped.

It consists of $A\times B\times C$ garbage pieces each of which has a value. The value of a piece may be 0, if the piece is neither profitable nor harmful, and may be negative which means that the piece is not just unprofitable, but even harmful (for environment).

The farmer thinks that he has too much harmful garbage, so he wants to decrease the heap size, leaving a rectangular nonempty parallelepiped of smaller size cut of the original heap to maximize the sum of the values of the garbage pieces in it. You have to find the optimal parallelepiped value. (Actually, if any smaller parallelepiped has value less than the original one, the farmer will leave the original parallelepiped).

Input

The first line of the input contains the number of the test cases, which is at most 15. The descriptions of the test cases follow. The first line of a test case description contains three integersA,B, and C (1 ≤ A, B, C ≤20). The next lines contain$A\cdot B\cdot C$ numbers, which are the values of garbage pieces. Each number does not exceed$2^{31}$ by absolute value. If we introduce coordinates in the parallelepiped such that the cell in one corner is(1,1,1) and the cell in the opposite corner is (A,B,C), then the values are listed in the order

$$\begin{gathered}(1,1,1),(1,1,2),\dots,(1,1,C),\\(1,2,1),\dots,(1,2,C),\dots,(1,B,C),\\(2,1,1),\dots,(2,B,C),\dots,(A,B,C).\end{gathered}$$

The test cases are separated by blank lines.

Output

For each test case in the input, output a single integer denoting the maximal value of the new garbage heap. Print a blank line between test cases.

Examples

InputOutput
12 2 2-1 2 0 -3 -2 -1 1 5
6


  A*B*C的立方体,每一块有自己的权值,求和最大的子立方体。

  以前做过二维的,是把二维的压缩成一维,然后当和最大子序列做的。这个三维的麻烦了,但思想是一样的。

  最坑的是减来减去加来加去的。。我是绕了半天。。

  如果用s[x][y][z]表示左上角(1,1,1),右下角(x,y,z)的立方体的权值和。那么s[x][y][z]=a[x][y][z]+s[x-1][y][z]+s[x][y-1][z]+s[x][y][z-1]-s[x-1][y-1][z]-s[x-1][y][z-1]-s[x][y-1][z-1]+s[x-1][y-1][z-1]。总之就是跟x,y,z隔一格的就是加,两格就是减。。。也就是距离奇数就加,偶数就减。再加上x,y,z这个点的权值。

  当已知全部的s。算左上角(x1,y1,z1),右下角(x2,y2,z2)这个立方体的权值,设dx=x2-x1+1,就等于s[x][y][z]-s[x-dx][y][z]-s[x][y-dy][z]-s[x][y][z-dz]+s[x-dx][y-dy][z]+s[x-dx][y][z-dz]+s[x][y-dy][z-dz]-s[x-dx][y-dy][z-dz]。和算s的区别就是奇数变成了减,偶数是加,丙并且原来的1变成了d,这个立方体该方向上方块的个数。

  上面这个计算方法变成几维的都能用。并且可以巧妙利用2进制来找到这些要加要减的坐标。

  枚举x1,x2,y1,y2,只用枚举z2就行了。设z1为1,z2从1遍历到C的过程中,不断记录当前遇到的(x1,y1,1),(x1,y1,z1)为左上角、右下角方块权值的最小值,用当前的值减去这个最小值,维护答案。

#include<cstdio>#include<algorithm>#include<iostream>#include<sstream>#include<cstring>#include<cmath>#include<queue>#include<map>#include<set>#define INF 0x3f3f3f3f#define MAXN 25#define MAXM 60#define eps 1e-9#define pii pair<int,int>#define FOR(i,s,t) for(i=s;i<=t;i++)using namespace std;int T,A,B,C;long long S[MAXN][MAXN][MAXN];void expand(int i,int &b0,int &b1,int &b2){    b0=i&1;    i>>=1;    b1=i&1;    i>>=1;    b2=i&1;}int sign(int b0,int b1,int b2){    return (b0+b1+b2)%2?1:-1;}long long sum(int x1,int x2,int y1,int y2,int z1,int z2){    int i,b0,b1,b2,dx=x2-x1+1,dy=y2-y1+1,dz=z2-z1+1;    long long ret=0;    FOR(i,0,7){        expand(i,b0,b1,b2);        ret-=S[x2-b0*dx][y2-b1*dy][z2-b2*dz]*sign(b0,b1,b2);    }    return ret;}int main(){    freopen("in.txt","r",stdin);    scanf("%d",&T);    while(T--){        scanf("%d%d%d",&A,&B,&C);        int x,y,z,b0,b1,b2,i;        memset(S,0,sizeof(S));        FOR(x,1,A) FOR(y,1,B) FOR(z,1,C) scanf("%lld",&S[x][y][z]);        FOR(x,1,A) FOR(y,1,B) FOR(z,1,C) FOR(i,1,7){            expand(i,b0,b1,b2);            S[x][y][z]+=S[x-b0][y-b1][z-b2]*sign(b0,b1,b2);        }        long long ans=-(1LL<<60);        int x1,x2,y1,y2;        FOR(x1,1,A) FOR(x2,x1,A) FOR(y1,1,B) FOR(y2,y1,B){            long long s,M=0;            FOR(z,1,C){                s=sum(x1,x2,y1,y2,1,z);                ans=max(ans,s-M);                M=min(M,s);            }        }        printf("%lld\n",ans);        if(T) puts("");    }    return 0;}


0 0