bzoj2228[ZJOI2011]礼物(gift)
据说联赛之前写题解可以涨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;
const int maxn=;
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)){
for(int i=;i<=n;++i){
for(int j=;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]);
for(int i=;i<=n;++i){
for(int j=;j<=m;++j){
for(int k=f[i-][j-]+;k>=;--k){
if(sum[i][j]-sum[i-][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 s[maxn],top=;
int rbound[maxn],lbound[maxn];//lbound:某个位置向左数第一个比它小的位置 rbound:某个位置向右数第一个比它小的位置
int work(int maxx,int maxy,int maxz,char getc(int,int,int)){
for(int i=;i<=maxx;++i){
dp(f[i],i,maxy,maxz,getc);//把第i层搞出来
}
int ans=;
for(int i=;i<=maxy;++i){
for(int j=;j<=maxz;++j){
top=;
s[]=;
for(int k=;k<=maxx;++k){
while(top!=&&f[k][i][j]<=f[s[top]][i][j])--top;
lbound[k]=s[top];
s[++top]=k;
}
s[]=maxx+;
top=;
for(int k=maxx;k>=;--k){
while(top!=&&f[k][i][j]<=f[s[top]][i][j])--top;
rbound[k]=s[top];
s[++top]=k;
}
for(int 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);
for(int i=;i<=p;++i){//没有读懂题目的坐标描述...瞎读呗,读错了也就相当于把坐标系换了一下
for(int j=;j<=q;++j){
scanf("%s",str[i][j]+);
}//printf("\n");
}
int ans=;
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);
return ;
}
bzoj2228[ZJOI2011]礼物(gift)的更多相关文章
- P3331 [ZJOI2011]礼物(GIFT)
题解: 首先转化为平面问题 对于每一个z,f(x,y)的值为它能向上延伸的最大高度 ...莫名其妙想出来的是n^4 以每个点作为右下边界n^3枚举再o(n)枚举左下边界计算z的最大值 然而很显然这种做 ...
- 【BZOJ2228】[ZJOI2011]礼物(单调栈)
[BZOJ2228][ZJOI2011]礼物(单调栈) 题面 BZOJ 洛谷 题解 如果这个玩意不是一个三维立方体,而是一个二维的矩形,让你在里面找一个最大正方形,那么全世界都会做. 丢到三维上?似乎 ...
- 礼物gift(DP)
这道题的DP非常的有意思…… 一开始我们总是会以为这是一个背包问题,直接dp[0] = 0,dp[j] += dp[j-c[i]]进行转移.之后统计一下从dp[m-minn]~dp[m]的答案之和为结 ...
- BZOJ 2228 礼物(gift)(最大子长方体)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2228 题意:给出一个只含有NP两种字母的长方体.从中找出只含有字母N的长方体,造型为a* ...
- [ZJOI2011]礼物
嘟嘟嘟 正是因为有这样的数据范围,解法才比较暴力. 我们假设取出的长方体常和宽相等,即\(a * a * b\).这样我们每次换两条边相等,搞三次就行. 那么对于第\(k\)层中的第\((i, j)\ ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- Java设计模式系列之桥接模式
桥接模式(Bridge)的定义 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?这就要使用桥接模式 将抽象部分与它的实现部分分离,使它们都可以独立地 ...
- [考试反思]1018csp-s模拟测试79:荒谬
对,如果你想把第5名粘进来,那么图片就是这么夸张. 然而和我并没有什么关系,实在是太菜了. 但是还是想吐槽出题人是真心没良心啊...做了达哥的良心题之后眼光极其挑剔 这套题的部分分设置非常愚蠢,唯一一 ...
- js设计模式-代理模式
1.什么是设计模式? 设计模式:在软件设计过程中常用的代码规范,针对特定的场景 2.应用场景: 麦当劳点餐 观察者模式 规定的代码格式 花店送花 :代理模式 真实对象(男同学)-----代理对 ...
随机推荐
- (二)Maven的安装与环境配置
想要安装 Apache Maven在Windows 系统上, 需要下载 Maven 的 zip 文件,并将其解压到你想安装的目录,并配置 Windows 环境变量. 所需工具 : 1.JDK 2.Ma ...
- 【转】2016/2017 Web 开发者路线图
链接:知乎 [点击查看大图] 原图来自LearnCodeAcademy最火的视频,learncode是YouTube上最火的Web开发教学频道,介绍包括HTML/CSS/JavaScript/Subl ...
- 在 ASP.NET MVC 中充分利用 WebGrid (microsoft 官方示例)
在 ASP.NET MVC 中充分利用 WebGrid https://msdn.microsoft.com/zh-cn/magazine/hh288075.aspx Stuart Leeks 下载代 ...
- Memcache学习整理
一.Memcache 是什么? 组成:程序进程管理.Socket 程序进程:Memcache把内存先分成几个大份,每一份分成多个小份.例如:小份中有5M...0.9M.0.8M.....0.1M,一份 ...
- -bash: .bash_profile: command not found
今天有一同事安装了ORACLE后,在切换账号时遇到错误提示"-bash: .bash_profile: command not found".如下所示 [root@GLETestL ...
- C++STL - 类模板
类的成员变量,成员函数,成员类型,以及基类中如果包含参数化的类型,那么该类就是一个类模板 1.定义 template<typename 类型形参1, typename 类型形参2,...&g ...
- java类加载器深入研究
看了下面几篇关于类的加载器的文章,豁然开朗.猛击下面的地址开始看吧. Java类加载原理解析 深入探讨 Java 类加载器 分析BootstrapClassLoader/ExtClassLo ...
- Error:Flash Download Failed-"Cortex-M3"
Error:Flash Download Failed-"Cortex-M3"出现一般有两种情况: 1.SWD模式下,Debug菜单中,Reset菜单选项(Autodetect/H ...
- ASP.NET Core--根据方案来限制身份
翻译如下: 在某些情况下,比如单页的应用程序,可以与多种认证来方式结合.例如,您的应用程序可能使用基于Cookie的身份验证来登录和JavaScript的请求承载认证.在某些情况下,可能一个授权验证的 ...
- markdown学习/mou
markdown编辑器mou markdown编辑器的使用很简单,mac平台选择课 MOU 这款比较轻的客户端. 使用也很方便,打开软件,->helo->mou help 就有各种示例,照 ...