传送门

参考资料:

  [1]:挑战程序设计竞赛

题意

  柱状图是由一些宽度相等的长方形下端对齐后横向排列得到的图形。

  现在有由 n 个宽度为1,高度分别为h[1,2,3.......n]的长方形从左到右依次排列组成的柱状图。

  问里面包含的长方形的最大面积是多少?

题解

  如果确定了长方形的左端点L和右端点R,那么最大可能的高度就是min{h[i] | L <= i <= R}。

  这样我们就得到了一个O(N3)的算法,如果对计算区间最小值进行一些优化,那么可以把复杂度将为O(N^2)。

  但即使是这样,仍然无法在规定时间内求出答案。那么我们应该怎么做才能更高效的求解呢?

  设面积最大的长方形左端是L,右端是R,高度是H。

  易得H[L-1] < H 且 H[R+1] < H ,H=min{h[ i ] | L <= i <= R} 。

  证明:

    如果H[L-1] >= H ,那么左端点就可以更新为L-1,从而可以得到更大的长方形,与假设矛盾,因此 H[L-1] < H;

  同理可得 H[R+1] < H。

  我们可以遍历一边,找到每个 i (i=1,2,3,......,n) 的最小的L[ i ]和最大的R[ i ];

  这样答案就是 max( h[i]*(R[i]-L[i]+1) ) (i=1,2,3,.........,n)。

  关键就是如何在线性时间内求出每个 i 的 L[ i ]和R[ i ]。

  由 H[L-1] < H && H[R+1] < H 可得:

  L[i]=( i 之前的高度第一个小于 h[i] 对应的下标) + 1;

  R[i]=( i 之后的高度第一个小于 h[i] 对应的下标) - 1;

  暴力方法当然是对于每个 i 都遍历一边 i 之前的值和 i 之后的值,这当然是会超时的,所以,我们要换个思路。

  引入一个新的数据结构栈;

  在计算 L[ i ] 时,首先,判断栈顶元素 j 的高度 h[ j ] 是否大于等于 h[ i ];

  如果h[ j ] ≥ h[ i ],则不断弹出栈顶元素,直到 h[ j ] < h[ i ] 或栈为空。

  若栈为空,则L[ i ] = 1,反之,L[ i ]=j+1,然后将 i 压入栈中。

  计算 R[ i ] 时只需反向( i 从n 到 1 )重复上述过程即可。

  由于栈的压入和弹出操作都是 O(N),因此整个算法的时间复杂度为 O(N);

•Code

 #include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
#define ll long long
const int maxn=1e5+; int n;
ll h[maxn];
int l[maxn];
int r[maxn];
stack<int >sta; void Clear()
{
while(!sta.empty())
sta.pop();
}
ll Solve()
{
Clear();
for(int i=;i <= n;++i)
{
while(!sta.empty() && h[sta.top()] >= h[i])
sta.pop(); l[i]=sta.empty() ? :sta.top()+;
sta.push(i);
} Clear();
for(int i=n;i >= ;--i)
{
while(!sta.empty() && h[sta.top()] >= h[i])
sta.pop(); r[i]=sta.empty() ? n:sta.top()-;
sta.push(i);
} ll ans=;
for(int i=;i <= n;++i)
ans=max(ans,h[i]*(r[i]-l[i]+)); return ans;
}
int main()
{
while(~scanf("%d",&n) && n)
{
for(int i=;i <= n;++i)
scanf("%lld",h+i); printf("%lld\n",Solve());
}
return ;
}

poj 2559(栈的应用)的更多相关文章

  1. [POJ 2559]Largest Rectangle in a Histogram 题解(单调栈)

    [POJ 2559]Largest Rectangle in a Histogram Description A histogram is a polygon composed of a sequen ...

  2. poj 2559 Largest Rectangle in a Histogram 栈

    // poj 2559 Largest Rectangle in a Histogram 栈 // // n个矩形排在一块,不同的高度,让你求最大的矩形的面积(矩形紧挨在一起) // // 这道题用的 ...

  3. stack(数组模拟) POJ 2559 Largest Rectangle in a Histogram

    题目传送门 /* 题意:宽度为1,高度不等,求最大矩形面积 stack(数组模拟):对于每个a[i]有L[i],R[i]坐标位置 表示a[L[i]] < a[i] < a[R[i]] 的极 ...

  4. POJ 2559 Program C

    Submit Status Practice POJ 2559 Description A histogram is a polygon composed of a sequence of recta ...

  5. poj 2559 Largest Rectangle in a Histogram (单调栈)

    http://poj.org/problem?id=2559 Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 6 ...

  6. POJ 2559 Largest Rectangle in a Histogram(单调栈)

    [题目链接] http://poj.org/problem?id=2559 [题目大意] 给出一些宽度为1的长方形下段对其后横向排列得到的图形,现在给你他们的高度, 求里面包含的最大长方形的面积 [题 ...

  7. 题解 POJ 2559【Largest Rectangle in a Histogram】(单调栈)

    题目链接:http://poj.org/problem?id=2559 思路:单调栈 什么是单调栈? 单调栈,顾名思义,就是单调的栈,也就是占中存的东西永远是单调(也就是递增或递减)的 如何实现一个单 ...

  8. POJ 2559 Largest Rectangle in a Histogram(单调栈) && 单调栈

    嗯... 题目链接:http://poj.org/problem?id=2559 一.单调栈: 1.性质: 单调栈是一种特殊的栈,特殊之处在于栈内的元素都保持一个单调性,可能为单调递增,也可能为单调递 ...

  9. poj 2559 Largest Rectangle in a Histogram - 单调栈

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19782 ...

随机推荐

  1. linux按时间查询日志

    在系统应用集中部署的时候,很多日志因为太多难以定位,获取某段时间的日志是对运维人员非常关键的事情. 一.sed查看某时间段到现在的系统日志: sed  -n  '/May 20 17/,$p'   / ...

  2. JarvisOJ Basic 爱吃培根的出题人

    听说你也喜欢吃培根?那我们一起来欣赏一段培根的介绍吧: bacoN is one of aMerICa'S sWEethEartS. it's A dARlinG, SuCCulEnt fOoD tH ...

  3. layui laydate设置当前日期往后不可选

    layui laydate设置当前日期往后不可选 laydate.render({ elem: '#demo', max: maxDate() }); // 设置最大可选的日期 function ma ...

  4. [WC2018]州区划分——FWT+DP+FST

    题目链接: [WC2018]州区划分 题目大意:给n个点的一个无向图,点有点权,要求将这n个点划分成若干个部分,每部分合法当且仅当这部分中所有点之间的边不能构成欧拉回路.对于一种划分方案,第i个部分的 ...

  5. Navicat MySQL 自动备份

    1 新建批处理作业 2 设定(多个库,就轮流选择不同库,然后步骤2) 最后记得保存 3 计划 4 设计批处理作业->设置计划任务 5 输入账号和密码 服务器登录名 服务器密码 6 你可以修改备份 ...

  6. Spring 学习笔记(二)

    spring 核心 (xml方式.注解方式) 两种方式实现 ioc :控制反转 aop : 面向切面

  7. Tmutarakan Exams URAL - 1091(莫比乌斯函数 || 容斥)

    题意: 求1 - s 中 找出k个数 使它们的gcd  > 1 求这样的k个数的对数 解析: 从每个素数的倍数中取k个数  求方案数 然后素数组合,容斥一下重的 奇加偶减 莫比乌斯函数的直接套模 ...

  8. 【NOI2003——搜索+二分图匹配优化】

    A 文本编辑器 无旋treap真好看 B 木棒游戏 暴力神仙题 C 数据生成器 树的直径两端点为Y, Z D 智破连环阵 搜索+二分图匹配优化 第一次写欸 列一下 void dfs (int y,in ...

  9. mysql安转过程中出现的问题! Fatal error: Can't open and lock privilege tables: Table 'mysql.user' doesn't exis

    net start mysql启动失败,报错信息如上,因缺少mysql这个库 所以跳过 在my.ini中添加 --skip-grant-tables 再启动mysql 然后进入mysql 倒入一个从其 ...

  10. poj3926 parade (单调队列+dp)

    题意:有n行路,每行路被分成m段,每一段有长度和权值,要求从最下面一行走到最上面一行某个位置,可以从相邻两行的同一列交点往上走,并且在同一行走的长度要<=K,求走过的最大权值 设f[i][j]为 ...