Histogram LightOJ - 1083
题意:给出一个直方图,由n个长条组成,它们的x轴上坐标分别为1-n,读入n之后读入的一行中,第i个表示x轴上坐标为i的长条长度。求直方图最大的正方形面积。
方法:
核心是求出每个长条向左右可以"扩展"的最大长度。
法一:单调栈
将n个元素的编号依次入栈。每次入栈前,设要入栈的编号为x,对应长度为l,将栈顶的编号对应的长度大于等于l的所有编号出栈(由于此题的一些特性,将“大于等于”改为“大于”也可以使用,但这不是标准的单调栈)。这之后,栈顶元素就是x能扩展到的最左端的端点减1(注意,是减1)。对于某个元素,其出栈的那一刻,使其出栈的x减一就是其能扩展到的最右侧的端点。
#include<cstdio>
#include<algorithm>
using namespace std;
int T,n,ans,len;
int st[],a[],l[],r[];
void push(int idx)
{
while(len>&&a[st[len]]>=a[idx]) r[st[len--]]=idx-;
l[idx]=st[len];
st[++len]=idx;
}
int main()
{
int i,TT;
scanf("%d",&T);
for(TT=;TT<=T;TT++)
{
scanf("%d",&n);
for(i=;i<=n;i++)
scanf("%d",&a[i]);
len=;
ans=;
for(i=;i<=n;i++)
push(i);
while(len>) r[st[len--]]=n;
for(i=;i<=n;i++)
ans=max(ans,a[i]*(r[i]-l[i]));
printf("Case %d: %d\n",TT,ans);
}
return ;
}
(由于题目的某些特性,即使单调栈在push时不把相同的pop出来也可以过。然而正确的单调栈一般都要把相同的也pop出来)
#include<cstdio>
#include<algorithm>
using namespace std;
int T,n,ans,len;
int st[],a[],l[],r[];
void push(int idx)
{
while(len>&&a[st[len]]>a[idx]) r[st[len--]]=idx-;
l[idx]=st[len];
st[++len]=idx;
}
int main()
{
int i,TT;
scanf("%d",&T);
for(TT=;TT<=T;TT++)
{
scanf("%d",&n);
for(i=;i<=n;i++)
scanf("%d",&a[i]);
len=;
ans=;
for(i=;i<=n;i++)
push(i);
while(len>) r[st[len--]]=n;
for(i=;i<=n;i++)
ans=max(ans,a[i]*(r[i]-l[i]));
printf("Case %d: %d\n",TT,ans);
}
return ;
}
法二:奇奇怪怪的方法,类似链表/kmp的预处理
left[i]和right[i]分别表示能扩展到的最左/右侧的高度小于等于它的长条的编号。看起来可能很慢,但是实际上均摊复杂度O(n)。
#include<cstdio>
#include<algorithm>
using namespace std;
int T,n,ans;
int a[],left[],right[];
int main()
{
int TT,i;
scanf("%d",&T);
for(TT=;TT<=T;TT++)
{
ans=;
scanf("%d",&n);
for(i=;i<=n;i++)
scanf("%d",&a[i]);
for(i=;i<=n;i++)
{
left[i]=i;
while(left[i]>&&a[left[i]-]>=a[i]) left[i]=left[left[i]-];
}
for(i=n;i>=;i--)
{
right[i]=i;
while(right[i]<n&&a[right[i]+]>=a[i]) right[i]=right[right[i]+];
}
for(i=;i<=n;i++)
ans=max(ans,a[i]*(right[i]-left[i]+));
printf("Case %d: %d\n",TT,ans);
}
}
法三:一个区间由区间最小值控制。对于某一个区间,答案要么包含这个最小值,要么在最小值左侧区间取,要么在右侧区间取。因此预处理解决RMQ,然后分治解决。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int T,TT,n;
int minn[][],a[];
int query(int l,int r)
{
int k=;
while((<<(k+))<=r-l+) ++k;
return a[minn[k][l]]>a[minn[k][r-(<<k)+]]?minn[k][r-(<<k)+]:minn[k][l];
}
int get(int l,int r)
{
if(l>r) return ;
if(l==r)
return a[l];
int pos=query(l,r);
return max(max(get(l,pos-),get(pos+,r)),a[pos]*(r-l+));
}
int main()
{
int i,j;
scanf("%d",&T);
for(TT=;TT<=T;TT++)
{
memset(minn,,sizeof(minn));
memset(a,,sizeof(a));
scanf("%d",&n);
for(i=;i<=n;i++)
scanf("%d",&a[i]);
for(i=;i<=n;i++)
minn[][i]=i;
for(i=;(<<i)<=n;i++)
for(j=;j<=n-(<<i)+;j++)
minn[i][j]=a[minn[i-][j]]>a[minn[i-][j+(<<(i-))]]?minn[i-][j+(<<(i-))]:minn[i-][j];
printf("Case %d: %d\n",TT,get(,n));
}
return ;
}
Histogram LightOJ - 1083的更多相关文章
- XJOI 3606 最大子矩形面积/LightOJ 1083 Histogram(单调栈/笛卡尔树)
A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rec ...
- 1083 - Histogram
1083 - Histogram PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 64 MB A hist ...
- lightoj刷题日记
提高自己的实力, 也为了证明, 开始板刷lightoj,每天题量>=1: 题目的类型会在这边说明,具体见分页博客: SUM=54; 1000 Greetings from LightOJ [简单 ...
- [LeetCode] Largest Rectangle in Histogram 直方图中最大的矩形
Given n non-negative integers representing the histogram's bar height where the width of each bar is ...
- poj 2559 Largest Rectangle in a Histogram - 单调栈
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19782 ...
- 区间DP LightOJ 1422 Halloween Costumes
http://lightoj.com/volume_showproblem.php?problem=1422 做的第一道区间DP的题目,试水. 参考解题报告: http://www.cnblogs.c ...
- LeetCode 笔记系列 17 Largest Rectangle in Histogram
题目: Largest Rectangle in Histogram Given n non-negative integers representing the histogram's bar he ...
- LeetCode: Largest Rectangle in Histogram(直方图最大面积)
http://blog.csdn.net/abcbc/article/details/8943485 具体的题目描述为: Given n non-negative integers represent ...
- LightOj 1298 - One Theorem, One Year(DP + 欧拉)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1298 题意:给你两个数 n, p,表示一个数是由前 k 个素数组成的,共有 n 个素数 ...
随机推荐
- PandoraBox 支持3G无线上网卡(电信卡3G卡)(三)
笔者采用的是华为EC122无线上网卡 一:编辑/etc/modules.d/60-usb-serial usbserial vendor=0x12d1 product=0x1505 二:编辑/et ...
- BZOJ 1042: [HAOI2008]硬币购物 容斥+背包
1042: [HAOI2008]硬币购物 Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请 ...
- Mac JDK 多版本共存
1. 安装各JDK版本,安装后通过Java -version检测是否安装好 2. 打开~/.bash_profile,没有的话创建 vim ~/.bash_profile ...
- linux网络配置及IP绑定
在学习时,参考了这篇文章:http://blog.csdn.net/collection4u/article/details/14127671:在这篇文章中作者讲述了VMware中虚机的三种网络模式: ...
- vue2实现自定义样式radio单选框
先上效果 <div class="reply"> 主编已回复: <div class="radio-box" v-for="(ite ...
- HashSe、LinkedHashSet、TreeSet(java基础知识十七)
1.HashSet存储字符串并遍历 * 特点:无序.无索引.无重复 HashSet存储字符串并遍历 HashSet<String> hs = new HashSet<>(); ...
- git push不成功 insufficient permission for adding an object to repository database
这常见于多用户. 1. 确保所有用户在同一个组: 2. 确保所有文件被组可读写. 当多个用户各自进行了push操作后,object目录下的文件可能各自属于各个用户.
- jsch上传文件功能
转载:http://www.cnblogs.com/longyg/archive/2012/06/25/2556576.html JSch是Java Secure Channel的缩写.JSch是一个 ...
- CreateRemoteThread注入DLL
DLL注入的常用方式之一远程线程注入,实现代码如下 // CreateRemoteThread.cpp : Defines the entry point for the application.// ...
- Android 业务组件化开发实践
组件化并不是新话题,其实很早很早以前我们开始为项目解耦的时候就讨论过的.但那时候我们说的是功能组件化.比如很多公司都常见的,网络请求模块.登录注册模块单独拿出来,交给一个团队开发,而在用的时候只需要接 ...