uva10755 - Garbage Heap

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
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

       */


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值