Garbage Heap
Farmer John has a heap of garbage formed in a rectangular parallelepiped.
It consists of 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 numbers, which are the values of garbage pieces. Each number does not exceed
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

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
Input | Output |
1 2 2 2 -1 2 0 -3 -2 -1 1 5 | 6 |
1)在降维,用累加和,计算一列中两个坐标中间的值时,要注意下标0 设为0, 从1开始。
2)在宏定义中慎用函数,只是简单替代,可能被执行多次,本题中,使用#define max(i,j) (i < j?j:i), 在程序中写max(ans, getresult());getresult()函数被执行了2次,调瞎了!
3)对多维的问题,通常通过降维降低算法复杂度,枚举部分边界,其他边界,通过其他问题解决。
#include <cstdlib>
#include <iostream>
#include <math.h>
#define FOR(i,s,t) for(int i = ( s); i < (t); i++)
using namespace std;
const int MAX = 20 + 3;
const long long INF = 1LL<<60;
void set_edg_0(long long cubic[MAX][MAX][MAX], int x, int y, int z)
{
for(int i = 0; i < y; i++ )
for(int j = 0; j < z; j++)cubic[0][i][j] = 0;
for(int i = 0; i < x; i++ )
for(int j = 0; j < z; j++)cubic[i][0][j] = 0;
for(int i = 0; i < x; i++ )
for(int j = 0; j < y; j++)cubic[i][j][0] = 0;
}
void genr_sum_cub(long long cubic[MAX][MAX][MAX], int x, int y, int z)
{
for(int i = 1; i <= x; i++)
for(int j = 1; j <= y; j++)
for(int k = 1; k <= z; k++)
cubic[i][j][k] += cubic[i - 1][j][k];
//for(int i = 0; i <= x; i++)
// for(int j = 1; j <= y; j++)
// {
// for(int k = 1; k <= z; k++)cout<< cubic[i][j][k]<<" ";
// cout<<endl;
// }
}
void get_sum_squer(long long cubic[MAX][MAX][MAX], long long squer[MAX][MAX], int x_start, int x_end, int y, int z)
{
for(int i =1 ; i <= y; i++)
for(int j = 1; j <= z; j++)
squer[i][j] = cubic[x_end][i][j] - cubic[x_start][i][j];
for(int i = 0; i <= y; i++)squer[0][i] = 0;
}
long long ans = -INF;
long long get_result(long long squer[MAX][MAX], int y, int z)
{
long long sum[MAX][MAX],i_jsum[MAX];
for(int i = 1; i <= y; i++)
for(int j = 1; j <= z; j++)
squer[i][j] += squer[i - 1][j];
long long m;
i_jsum[0] = 0;
for(int i = 0; i <= y; i++)
for(int j = i + 1; j <= y; j++)
{
for(int k = 1; k <= z; k++)i_jsum[k] = squer[j][k] - squer[i][k];
for(int k = 1; k <= z; k++)i_jsum[k] += i_jsum[k - 1];
m = i_jsum[0];
for(int k = 1; k <= z; k++)
{
if(ans < i_jsum[k] - m) ans = i_jsum[k] - m;
if(m > i_jsum[k])m = i_jsum[k];
}
//cout<<"ans:"<<ans<<endl;
}
//cout << "ans==>"<<ans<<endl;
return ans;
}
long long caculate(long long cub[MAX][MAX][MAX],int x,int y,int z)
{
if(x==0 && y == 0 && z == 0)return 0;
long long squer[MAX][MAX];
genr_sum_cub(cub,x,y,z);
long long ans = -INF;
for(int i = 0; i <= x; i++)
for(int j = i + 1; j <= x; j++)
{
get_sum_squer(cub,squer,i,j,y,z);
long long r = get_result(squer,y,z);
// ans = max(ans, r);不要在宏定义里 用函数
if(ans < r)ans = r;
// cout <<"--------------------------------------"<<ans<<endl;
}
return ans;
}
int main(int argc, char *argv[])
{
int t,a,b,c;
long long cubic[MAX][MAX][MAX];
set_edg_0(cubic, MAX, MAX, MAX);
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&a,&b,&c);
for(int i = 1; i <= a; i++)
for(int j = 1; j <= b; j++)
for(int k =1; k <= c; k++)
scanf("%lld",&cubic[i][j][k]);
cout<<caculate(cubic,a,b,c)<<"\n"<<endl;
}
// system("PAUSE");
return EXIT_SUCCESS;
}
/*
5
3 3 3
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
*/