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 个素数 ...
随机推荐
- JavaScript提高:001:ASP.NET使用easy UI
jQuery EasyUI是一组基于jQuery的UI插件集合.能够简洁的开发出功能多内容丰富的界面,而不须要开发人员自己费力的写那些复杂的js代码.本文简介在ASP.NET开发中引用这些js文件和样 ...
- 项目Beta冲刺(团队5/7)
项目Beta冲刺(团队5/7) 团队名称: 云打印 作业要求: 项目Beta冲刺(团队) 作业目标: 完成项目Beta版本 团队队员 队员学号 队员姓名 个人博客地址 备注 221600412 陈宇 ...
- Android经常使用的工具类
主要介绍总结的Android开发中经常使用的工具类,大部分相同适用于Java. 眼下包含HttpUtils.DownloadManagerPro.ShellUtils.PackageUtils. Pr ...
- scala快速学习笔记(三):Collections,包
VI.Collections 1.Array 一些常用方法:println, map( _ * 2), filter(_ % 2 == 0), sum, reserve Array是不可变的, ...
- JSP复习笔记
1.注释 <!--这个注释会显示在HTML源码中--> <%--隐藏注释,不会显示在HTML源码中--%> 2.声明 <%! java声明 声明变量,方法等 %> ...
- strong and weak 强引用和弱引用的差别
(weak和strong)不同的是 当一个对象不再有strong类型的指针指向它的时候 它会被释放 ,即使还有weak型指针指向它. 一旦最后一个strong型指针离去 .这个对象将被释放,全部剩余 ...
- js中!~什么意思
(function () { var names = []; return function (name) { addName(name); } function addName(name) { if ...
- POJ1094 Sorting It All Out —— 拓扑排序
题目链接:http://poj.org/problem?id=1094 Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Tot ...
- vue开发:移动端图片上传
因为最近遇到个移动端上传头像的需求,上传到后台的数据是base64位,其中为了提高用户体验,把比较大的图片用canvas进行压缩之后再进行上传.在移动端调用拍照功能时,会发生图片旋转,为了解决这个问题 ...
- html5--6-24 css3前缀
html5--6-24 css3前缀 学习要点 掌握css3前缀的使用 CSS3目前很多新增属性尚未被W3C列为标准,对这些暂时未被公布为标准的属性,各家浏览器会在属性前加上前缀词,也将其称之为浏览器 ...