ACM: uva_10755

来源:互联网 发布:电脑网络连接显示未知 编辑:程序博客网 时间:2024/06/10 12:59

Garbage Heap

Farmer John has a heap of garbage formed in a rectangularparallelepiped.

It consists of   garbagepieces each of which has a value. The value of a piece may be 0, ifthe piece is neither profitable nor harmful, and may be negativewhich means that the piece is not just unprofitable, but evenharmful (for environment).

 

 

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

 

Input

The first line of the input contains the numberof the test cases, which is at most 15. The descriptions of thetest cases follow. The first line of a test case descriptioncontains three integers A, B,and (1 ≤A, B, C ≤ 20).The next lines contain   numbers,which are the values of garbage pieces. Each number does notexceed   by absolute value. If weintroduceccoordinates in the parallelepiped such that the cell inone corner is (1,1,1) and thecell in the opposite corner is (A,B,C), then thevalues are listed in the order

 

The test cases are separated by blank lines.

 

Output

For each test case in the input, output a single integerdenoting the maximal value of the new garbage heap. Print a blankline between test cases.

 

Examples

1

2 2 2

-1 2 0 -3 -2 -1 1 5

Output

6

 

题意: 在一个长方体中, 每个单位正方体1*1*1的体积是1, 现在要你找出体积最大子长方体.

 

解题思路:

     1.跟二维的求和一样, sum[i][j] = sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];

       推广三维情况, sum[i][j][k] =∑(sum[i-s1][j-s2][k-s3])+a[i][j][k];

       这样枚举复杂度 O(n^5);

代码:

 #include<cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 30
const long long INF = (1LL<<60);

int a, b, c;
long long s[MAX][MAX][MAX];

inline long long min(long long a, long long b)
{
 return a < b ? a : b;
}

inline long long max(long long a, long long b)
{
 return a > b ? a : b;
}

void situation(int i, int &s1, int&s2, int &s3)
{
 s1 = i&1;
 i >>= 1;
 s2 = i&1;
 i >>= 1;
 s3 = i&1;
}

int getSign(int s1, int s2, int s3)
{
 return (s1+s2+s3)%2 == 1 ? 1 : -1;
}

long long getSum(int x1, int x2, int y1, int y2, int z1, intz2)
{
 int dx = (x2-x1+1), dy = (y2-y1+1), dz =(z2-z1+1);
 long long sum = 0;
 for(int i = 0; i < 8; ++i)
 {
  int s1, s2, s3;
  situation(i, s1, s2, s3);
  sum -=s[x2-dx*s1][y2-dy*s2][z2-dz*s3]*getSign(s1, s2, s3);
 }
 return sum;
}

int main()
{
 int i, j, k;
// freopen("input.txt", "r", stdin);
 int caseNum;
 scanf("%d", &caseNum);
 while(caseNum--)
 {
  scanf("%d %d %d",&a, &b, &c);
  memset(s, 0, sizeof(s));
  for(i = 1; i <=a; ++i)
   for(j = 1; j<= b; ++j)
    for(k=1; k <= c; ++k)
     scanf("%lld",&s[i][j][k]);
  
  for(int i = 1; i<= a; ++i)
  {
   for(int j =1;j <= b; ++j)
   {
    for(intk = 1; k <= c; ++k)
    {
     for(intp = 1; p < 8; ++p)
     {
      ints1, s2, s3;
      situation(p,s1, s2, s3);
      s[i][j][k]+= s[i-s1][j-s2][k-s3]*getSign(s1, s2, s3);
     }
    }
   }
  }
  
  long long result = -INF;
  for(int x1 = 1; x1<= a; ++x1)
  {
   for(int x2 =x1; x2 <= a; ++x2)
   {
    for(inty1 = 1; y1 <= b; ++y1)
    {
     for(inty2 = y1; y2 <= b; ++y2)
     {
      longlong temp  =0;
      for(intz = 1; z <= c; ++z)
      {
       longlong sum = getSum(x1, x2, y1, y2, 1, z);
       result= max(result, sum - temp);
       temp= min(temp, sum);
      }
     }
    }
   }
  }
  
  printf("%lld\n", result);
  if(caseNum) printf("\n");
 }
 return 0;
}

 

0 0
原创粉丝点击