p1164【立方体求和】

  题目:

SubRaY有一天得到一块西瓜,是长方体形的....
SubRaY发现这块西瓜长m厘米,宽n厘米,高h厘米.他发现如果把这块西瓜平均地分成m*n*h块1立方厘米的小正方体,那么每一小块都会有一个营养值(可能为负,因为西瓜是有可能坏掉的,但是绝对值不超过200).
现在SubRaY决定从这m*n*h立方厘米的西瓜中切出mm*nn*hh立方厘米的一块小西瓜(一定是立方体形,长宽高均为整数),然后吃掉它.他想知道他最多能获得多少营养值.(0<=mm<=m,0<=nn<=n,0<=hh<=h.mm,nn,hh的值由您来决定).
换句话说,我们希望从一个m*n*h的三维矩阵中,找出一个三维子矩阵,这个子矩阵的权和最大.

一个2*3*4的例子,最优方案为切红色2*3*1部分

输入格式 Input Format
首行三个数h,m,n(注意顺序),分别表示西瓜的高,长,宽.
以下h部分,每部分是一个m*n的矩阵,第i部分第j行的第k个数表示西瓜第i层,第j行第k列的那块1立方厘米的小正方体的营养值.

输出格式 Output Format
SubRaY所能得到的最大营养值

样例输入 Sample Input
2 3 4
4 1 2 8
0 5 -48 4
3 0 1 9
2 1 4 9
1 0 1 7
3 1 2 8

样例输出 Sample Output
45

时间限制 Time Limitation
1s

注释 Hint
对于30%的数据,h=1,1<=m,n<=10
对于全部的数据,1<=h<=32,1<=m,n<=50,保证h<=m,n

来源 Source
noip 模拟赛

    因为数据比较小,所以不会超时的。你先处理下这一层这个位置和上个位置的累加和,然后在处理每一列的累加和。

   然后每次运算只用从左开始往右进行累加,算的就是一个矩阵了。

    

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int a[52][52][52];
int c[52][52][52];
int b[1000];
int p[1000];
int main()
{
    int h,m,n;//高,长,宽
    cin>>h>>m>>n;
    for(int w=1;w<=h;w++)
    {
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
                cin>>a[w][i][j],c[w][i][j]=a[w][i][j];
        }
    }
    for(int w=1;w<=h;w++)
    {
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
            {
                c[w][i][j]+=c[w-1][i][j];
            }
        }
    }
    for(int w=1;w<=h;w++)
    {
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
            {
                c[w][i][j]+=c[w][i-1][j];
            }
        }
    }
    /*cout<<endl;
    for(int w=1;w<=h;w++)
    {
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
            {
                cout<<c[w][i][j]<<‘ ‘;
            }
            cout<<endl;
        }
    }*/
    int ans=0;
    for(int w=1;w<=h;w++)//第几层
    {
        for(int H=1;H<=w;H++)//w层上面选几层
        {
            for(int i=1;i<=m;i++)//第i行
            {
                for(int t=1;t<=i;t++)//这行上面的t行
                {
                    memset(b,0,sizeof(b));
                    memset(p,0,sizeof(p));
                    for(int k=1;k<=n;k++)//从左往右加
                    {
                        p[k]=c[w][i][k]-c[H-1][i][k]-c[w][t-1][k]+c[H-1][t-1][k];
                        b[k]=max(b[k-1]+p[k],p[k]);
                        if(b[k]>ans)
                            ans=b[k];
                    }
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

程序里有标注

时间: 2024-10-29 19:08:18

p1164【立方体求和】的相关文章

[转]树状数组的一些应用

树状数组(BIT,Binary Indexed Tree) 先上一张经典的图吧.(也是盗的,地址见水印 以下转自:http://blog.csdn.net/lawrence_jang/article/details/8054173 1.单点增减+区间求和 思路:C[x]表示该点的元素:sum(x)=C[1]+C[2]+……C[x] int arr[MAXN]; inline int sum(int x){int res=0;while(x)res+=arr[x],x-=lowbit(x);ret

HTML5 CSS3 诱人的实例: 3D立方体旋转动画

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/34120047 创意来自:http://www.html5tricks.com/demo/html5-3d-cube/index.html , 同学给我发的样例,感觉非常不错,只是实在想不出来实际的用处.可是效果非常炫~ 效果图: 知识点: 1.perspective ,transform 的复习 2.css3 backgroud实现格格背景.即面上的小格格 3. @-webki

cogs 36.求和问题

36. 求和问题 ★   输入文件:sum.in   输出文件:sum.out   简单对比时间限制:1.2 s   内存限制:128 MB [问题描述] 在一个长度为n的整数数列中取出连续的若干个数,并求它们的和. [输入格式] 输入由若干行组成,第一行有一个整数n    第二行有n个整数    第三行有一个整数m    下面m行,每行两个整数i与j(i<=j),表示求和的起始和终止位置. [输出格式] 输出有m行, 每行一个整数,表示这个数段数列的和. [输入样例] 输入文件 82 3 4

css3立方体实现

使用css3实现一个立方体 <div class="box"> <div class="boxCorner1"></div> <div class="boxCorner2"></div> </div> .box { margin:4em auto; width:10em; height:10em; transform-style:preserve-3d; transform-

立方体类公用抽象类

写一个程序,定义抽象基类Shape,由它派生出3个派生类,Circle(圆形).Rectangle(矩形).Triangle(三角形).用如下的main()函数,求出定义的几个几何体的面积和 程序代码 #include <iostream> using namespace std; class CSolid//立方体类 { public: //计算立方体的表面积 virtual double Area() = 0; //计算立方体的体积 virtual double Volume() = 0;

使用Linq求和方法Sum计算集合中多个元素和时应该注意的性能问题

提出问题 本文使用下面的实例来说明问题,以下是实例的完整代码. //************************************************************ // // Sum应用示例代码 // // Author:三五月儿 // // Date:2014/09/10 // // http://blog.csdn.net/yl2isoft // //**********************************************************

杭电 2015 偶数求和

http://acm.hdu.edu.cn/showproblem.php?pid=2015 偶数求和 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 45044    Accepted Submission(s): 19675 Problem Description 有一个长度为n(n<=100)的数列,该数列定义为从2开始的递增有序

HDU4027 Can you answer these queries 线段树区间求和+剪枝

给了你n,然后n个数字在一个数组中,接下来m个询问,每个询问三个数字 t,x,y,若t==0,那么修改区间[x,y]的每一个值,变为原来每个位置上的数 开根号取整,若t==1,那么对区间[x,y]求和 由于n,m,很大,所以树状数组铁定超时,若直接用线段树来做区间修改,那么也是超时,这类题目没别的方法了,静心剪枝,发现题目给的数据范围为2^63,有没有发现,2^63开根号 绝对不需要开10次,就能到1,到1以后就不需要再开了,意思就是若有某个区间[x,y]每一个点的值都为1时,这一段区间事实上是

7.03 对某列的值求和

问题:计算某个列中所有值的和,例如,计算所有职员的工资总额.解决方案:如果将整个表作为一个组或一个窗口求和,则只需对相应列使用SUM函数,而不要使用GROUP BY 子句:select sum(sal) from emp 如果创建了多个数据组或多个窗口,则使用SUM函数的同时,还要使用GROUP BY子句.下面例子将按部门计算职员的工资总额:select deptno,sum(sal) as total_for_dept from emp group by deptno;