据说联赛之前写题解可以涨RP

这题的输入格式半天没看懂…其实是有q层摞在一起,每一层大小都是p*r,依次输入q层的情况。那么首先我们枚举三种挖方块的姿势,分别使切出的方块的上面/前面/右面是正方形的面。考虑其中的一种姿势,我们可以O(n^2)枚举正方形的面在原先的大立方体中的右下角坐标(i,j),那么大正方体的每一层中以(i,j)为右下角的完好正方形都有一个最大边长,我们把这些最大边长拿出来形成一个序列。因为最优方案中一定有一个位置的正方形达到了最大边长(否则一定可以得到边长更大的解),所以我们枚举达到最大边长的正方形在哪个位置,找出它最多向两边延伸到哪里,也就是找到两边第一个比它小的最大边长的位置,这一步可以单调栈O(n)枚举所有位置.加起来是O(n^3)

中间还有一步,求以每个位置为右下角的完好正方形最大边长。记某一层以(i,j)为右下角的完好正方形最大边长为f[i][j],那么f[i][j]<=f[i-1][j-1]+1因此我们从f[i-1][j-1]+1开始从大到小枚举f[i][j]的可能取值,只需判断比f[i-1][j-1]多出来的那一部分(第i行和第j列的对应位置)是否全部完好无损即可,找到第一个合法的结果时就跳出循环.每一层的DP看起来都是O(n^3)的,但其实是O(n^2)的。考虑f[1][2],f[2][3],f[3][4],f[4][5]…..,它们所对应的最大完好正方形的上边界是单调下降的,因此对于这一条斜线上的所有状态总的枚举量为O(n).斜线的数目也是O(n)的,因此一层的复杂度是O(n^2),一共n层, DP的总复杂度为O(n^3)

枚举挖方块的姿势的时候,我的写法比较丑,认为是把输入的大立方体旋转到三种不同的姿势,每次都让削出的正方形的面在y轴和z轴确定的平面内(也就是说,分别让大立方体的上面/前面/右面位于yOz平面内)。实现的时候写了三个在不同坐标系下找到对应位置的函数,计算的时候把函数指针传进去,高维数组寻址常数炸天…

#include<cstdio>

#include<algorithm>

using namespace std;

;

char str[maxn][maxn][maxn];

//三种切木块的姿势

char get1(int x,int y,int z){

    return str[x][y][z];

}

char get2(int x,int y,int z){

    return str[y][x][z];

}

char get3(int x,int y,int z){

    return str[y][z][x];

}

int f[maxn][maxn][maxn];//f[i][j][k]:第i层的(j,k)为右下角的最大完好正方形

int sum[maxn][maxn];

void dp(int f[maxn][maxn],int x,int n,int m,char getc(int,int,int)){

    ;i<=n;++i){

        ;j<=m;++j){

           // if(getc(x,i,j)=='P')printf("%d %d %d\n",x,i,j);

            sum[i][j]=sum[i-][j]+sum[i][j-]-sum[i-][j-]+(getc(x,i,j)=='P');      

        }//sum[i][j]:在(i,j)左上方有多少坏格子

    }//printf("%d\n",sum[n][m]);

    ;i<=n;++i){

        ;j<=m;++j){

            ][j-]+;k>=;--k){

                ][j]-sum[i][j-k]+sum[i-][j-k]==&&sum[i][j]-sum[i][j-]-sum[i-k][j]+sum[i-k][j-]==){

                    f[i][j]=k;

                    break;

                }

            }

        }

    }

}

;

int rbound[maxn],lbound[maxn];//lbound:某个位置向左数第一个比它小的位置 rbound:某个位置向右数第一个比它小的位置

int work(int maxx,int maxy,int maxz,char getc(int,int,int)){

    ;i<=maxx;++i){

        dp(f[i],i,maxy,maxz,getc);//把第i层搞出来

    }

    ;

    ;i<=maxy;++i){

        ;j<=maxz;++j){

            top=;

            s[]=;

            ;k<=maxx;++k){

                &&f[k][i][j]<=f[s[top]][i][j])--top;

                lbound[k]=s[top];

                s[++top]=k;

            }

            s[]=maxx+;

            top=;

            ;--k){

                &&f[k][i][j]<=f[s[top]][i][j])--top;

                rbound[k]=s[top];

                s[++top]=k;

            }

            ;k<=maxx;++k){

                ans=max(ans,*(rbound[k]-lbound[k]-)*f[k][i][j]);

              //  if(4*(rbound[k]-lbound[k]-1)*f[k][i][j]==40)printf("%d %d %d %d %d\n",rbound[k]-lbound[k]-1,f[k][i][j],k,i,j);

            }

        }

    }//printf("%d\n",ans);

    return ans;

}

int main(){

    int p,q,r;scanf("%d%d%d",&q,&p,&r);

    ;i<=p;++i){//没有读懂题目的坐标描述...瞎读呗,读错了也就相当于把坐标系换了一下

        ;j<=q;++j){

            scanf();

        }//printf("\n");

    }

    ;

    ans=max(ans,work(p,q,r,get1));

    ans=max(ans,work(q,p,r,get2));

    ans=max(ans,work(r,p,q,get3));

    printf("%d\n",ans);

    ;

}

bzoj2228[ZJOI2011]礼物(gift)的更多相关文章

  1. P3331 [ZJOI2011]礼物(GIFT)

    题解: 首先转化为平面问题 对于每一个z,f(x,y)的值为它能向上延伸的最大高度 ...莫名其妙想出来的是n^4 以每个点作为右下边界n^3枚举再o(n)枚举左下边界计算z的最大值 然而很显然这种做 ...

  2. 【BZOJ2228】[ZJOI2011]礼物(单调栈)

    [BZOJ2228][ZJOI2011]礼物(单调栈) 题面 BZOJ 洛谷 题解 如果这个玩意不是一个三维立方体,而是一个二维的矩形,让你在里面找一个最大正方形,那么全世界都会做. 丢到三维上?似乎 ...

  3. 礼物gift(DP)

    这道题的DP非常的有意思…… 一开始我们总是会以为这是一个背包问题,直接dp[0] = 0,dp[j] += dp[j-c[i]]进行转移.之后统计一下从dp[m-minn]~dp[m]的答案之和为结 ...

  4. BZOJ 2228 礼物(gift)(最大子长方体)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2228 题意:给出一个只含有NP两种字母的长方体.从中找出只含有字母N的长方体,造型为a* ...

  5. [ZJOI2011]礼物

    嘟嘟嘟 正是因为有这样的数据范围,解法才比较暴力. 我们假设取出的长方体常和宽相等,即\(a * a * b\).这样我们每次换两条边相等,搞三次就行. 那么对于第\(k\)层中的第\((i, j)\ ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. Java设计模式系列之桥接模式

    桥接模式(Bridge)的定义 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?这就要使用桥接模式 将抽象部分与它的实现部分分离,使它们都可以独立地 ...

  8. [考试反思]1018csp-s模拟测试79:荒谬

    对,如果你想把第5名粘进来,那么图片就是这么夸张. 然而和我并没有什么关系,实在是太菜了. 但是还是想吐槽出题人是真心没良心啊...做了达哥的良心题之后眼光极其挑剔 这套题的部分分设置非常愚蠢,唯一一 ...

  9. js设计模式-代理模式

    1.什么是设计模式? 设计模式:在软件设计过程中常用的代码规范,针对特定的场景 2.应用场景: 麦当劳点餐  观察者模式   规定的代码格式 花店送花  :代理模式 真实对象(男同学)-----代理对 ...

随机推荐

  1. 【8-22】java学习笔记04

    java基础类库 Scanner类(java.util.scanner) Scanner对象.hasNextXxx(),hasNext()默认方法为字符串://Returns true if this ...

  2. Http(2)

    1.传递的请求参数如何获取 GET方式: 参数放在URI后面 POST方式: 参数放在实体内容中 核心的API: request.getParameter("参数名");  根据参 ...

  3. 【原创】leetCodeOj --- Dungeon Game 解题报告

    原题地址: https://oj.leetcode.com/problems/dungeon-game/ 题目内容: The demons had captured the princess (P) ...

  4. ConditionalOnBean 与 ConditionalOnMissingBean 的正确玩法

    之前看到这篇博客,写ConditionalOnClass的用法,自己实践了一下,感觉有点问题,原文如下: https://blog.csdn.net/lucyTheSlayer/article/det ...

  5. 【iCore4 双核心板_uC/OS-II】例程四:软件定时器

    一.实验说明: 一些应用程序执行它们的任务时需要延迟一段特定的时间,因此uC/OS-II为我们提供了一些相应的 延时函数,本例程我们使用软件定时器定时500ms点亮相应的LED实现三色LED循环闪烁. ...

  6. java中微信统一下单采坑(app微信支付)

    app支付前java后台统一下单文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1 微信支付接口签名校验工具:https ...

  7. ELK-elasticsearch-6.3.2插件【head,bigdesk,cerebro[kopf]】安装

    参考博客:linux下ElasticSearch.6.2.2集群安装与head.Kibana.X-Pack..插件的配置安装 参考博客:ELK5.5.1 插件安装实践纪要(head/bigdesk/k ...

  8. 转:UML工具Astah的使用

    原文链接:http://blog.csdn.net/vipygd/article/details/9182247 前言 UML是软件工程中非常重要的知识点.我们经常要去展示各种UML图,当然,我们要将 ...

  9. 好吧,我承认我是爱瞎折腾----利用YDUI改变页面UI

    上周恒丰代付接口上线投产后,我做了一个“恒丰代付检查工具”,用途是,当线上调用恒丰代付出现了问题订单时,可以在这个工具页里做相应的弥补. 我项目里其他一些工具页的UI用的是YDUI.YDUI号称是“一 ...

  10. Win10 取消桌面快捷键图标

    新建文本文档 --- 写入如下内容 --- 改名为 .bat 并运行 @echo off color 2 reg delete HKCR\lnkfile /v IsShortcut /f reg de ...