HDU 1506 Largest Rectangle in a Histogram(单调栈、笛卡尔树)
题意:给定n个连续排列的矩形的高,矩形的宽都为1。问最大矩形覆盖。
例如:n = 7,h[i] = (2 1 4 5 1 3 3),最大覆盖为8。
Sample Input
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0 Sample Output
8
4000
题解:
首先可以确定,最大矩形的高一定等于某个矩形的高,宽一定等于某个矩形可以向两边最大可以延伸到的范围。
维护一个非降序的单调栈,然后依次枚举矩形的高 h[i]。
当 h[i] > top()时,说明 h[i] 向左最多可以延伸到 top() + 1,然后将 i 入栈。
当 h[i] < top()时,说明 top 向右最多可以延伸到 i - 1,为了满足栈的单调,栈顶元素要不断出栈,然后按 h[i] > top()的情况处理。
最后扫一遍,找最大的 (r[i] - l[i] + 1) * h[i],就是答案。
h[i] == top() 呢?不用管。
可以看出,对于有两个以上的矩形等价(这里的等价指的是,矩形高度相同,他们的最大延伸范围也相同)时,上面处理得到的 l[i] 和 r[i] 只有其中一个的答案会是他们最大的延伸范围,所以并不影响答案。所以维护的单调栈可以是单调不降的,也可以是单调递增的。
例如:4 4 4 4,上面求出的延伸范围是(1, 4) (2, 4) (3, 4) (4, 4)。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
typedef long long LL;
const int maxn = ;
const LL INF = 1e16; int a[maxn];
LL l[maxn], r[maxn]; int main()
{
int n;
while(~scanf("%d", &n) && n)
{
for (int i = ; i <= n; i++) scanf("%d", &a[i]); stack<int> st;
st.push(), a[n+] = ;
for (int i = ; i <= n+; i++)
{
//若是这里改成 >= 来维护单调递增的栈的话,判断应该加一个 && (a[st.top() | a[i]),防止栈空。
while(a[st.top()] > a[i])
r[st.top()] = i-, st.pop();
l[i] = st.top()+;
st.push(i);
} LL ans = -INF;
for (int i = ; i <= n; i++)
ans = max(ans, 1ll * (r[i]-l[i]+) * a[i]); printf("%lld\n", ans);
}
}
另一种做法就是笛卡尔树了。
笛卡尔树满足的条件:
1、左子树的下标 < 根节点 < 右子树
2、根节点的值是子树中所有点的最值。
可以看出,对一颗笛卡尔树中序遍历即可得到原序列。
故此题可以构造一个笛卡尔树,答案就是所有子树中 MAX(子树结点 × 根节点的值)。
笛卡尔树可以借助单调栈构建:
按照序列的顺序,每加入一个 a[i] 时,
若栈顶元素 > a[i],则不断弹出栈顶,使栈满足单调。将最后一个被弹出的做为 i 的左儿子。(因为这一段被弹出的下标都小于 i ,并且值都大于 a[i])
然后将 i 入栈,做为原本栈顶的儿子。
时间复杂度O(n)。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
typedef long long LL;
const int maxn = ;
const LL INF = 1e16; int a[maxn], lson[maxn], rson[maxn], fa[maxn];
LL dp[maxn];
LL ans, tmp; LL DP(int id)
{
if (id == ) return ;
if (dp[id]) return dp[id];
dp[id] = DP(lson[id]) + DP(rson[id]) + ;
ans = max(ans, 1ll * dp[id] * a[id]);
return dp[id];
} int main()
{
int n;
while(~scanf("%d", &n) && n)
{
for (int i = ; i <= n; i++) scanf("%d", &a[i]); stack<int> st;
memset(lson, , sizeof(lson));
memset(rson, , sizeof(rson));
memset(dp, , sizeof(dp));
memset(fa, , sizeof(fa)); for (int i = ; i <= n; i++)
{
if (!st.empty() && a[st.top()] > a[i])
{
while (!st.empty() && a[st.top()] > a[i])
tmp = st.top(), st.pop();
lson[i] = tmp, fa[tmp] = i;
}
if (!st.empty()) rson[st.top()] = i, fa[i] = st.top();
st.push(i);
} ans = -INF;
for (int i = ; i <= n; i++) if (!fa[i]) DP(i); printf("%lld\n", ans);
}
}
HDU 1506 Largest Rectangle in a Histogram(单调栈、笛卡尔树)的更多相关文章
- HDU - 1506 Largest Rectangle in a Histogram (单调栈/笛卡尔树)
题意:求一个直方图中最大矩形的面积. 很经典的一道问题了吧,可以用单调栈分别求出每个柱子左右两边第一个比它低的柱子(也就相当于求出了和它相连的最后一个比它高的柱子),确定每个柱子的左右边界,每个柱子的 ...
- hdu 1506 Largest Rectangle in a Histogram(单调栈)
L ...
- HDU 1506 Largest Rectangle in a Histogram (dp左右处理边界的矩形问题)
E - Largest Rectangle in a Histogram Time Limit:1000MS Memory Limit:32768KB 64bit IO Format: ...
- HDU 1506 Largest Rectangle in a Histogram set+二分
Largest Rectangle in a Histogram Problem Description: A histogram is a polygon composed of a sequenc ...
- hdu 1506 Largest Rectangle in a Histogram 构造
题目链接:HDU - 1506 A histogram is a polygon composed of a sequence of rectangles aligned at a common ba ...
- HDU 1506 Largest Rectangle in a Histogram(区间DP)
题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1506 题目: Largest Rectangle in a Histogram Time Limit: ...
- DP专题训练之HDU 1506 Largest Rectangle in a Histogram
Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base l ...
- Hdu 1506 Largest Rectangle in a Histogram 分类: Brush Mode 2014-10-28 19:16 93人阅读 评论(0) 收藏
Largest Rectangle in a Histogram Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...
- hdu 1506 Largest Rectangle in a Histogram——笛卡尔树
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1506 关于笛卡尔树的构建:https://www.cnblogs.com/reverymoon/p/952 ...
随机推荐
- php 转码函数 你还在用iconv吗?-- 解决sqlserver插入中文失败问题
文章来源 :http://www.veryhuo.com/a/view/41348.html 这次给客户同步sqlserver数据,临时搭的 PHP Query Analyzer 插入某些中文一直有些 ...
- SpringBoot | 第三十七章:集成Jasypt实现配置项加密
前言 近期在进行项目安全方面评审时,质量管理部门有提出需要对配置文件中的敏高文件进行加密处理,避免了信息泄露问题.想想前段时间某公司上传github时,把相应的生产数据库明文密码也一并上传了,导致了相 ...
- Day3上
T1 星空[问题描述]你是能看到第一题的friends 呢.——hja点点星空是一张
- 微软AI发布会,集齐六大亮点召唤黑科技!
7月12日,微软合作伙伴大会Inspire在华盛顿特区如火如荼地举行.同一天,在相隔5个时区的伦敦,微软还举办了一场关于人工智能的发布会.这是一场智能技术和情感体验两相交融的科技盛宴,既有黑科技,也有 ...
- 详细讲解:tp3.2.3生成验证码并进行验证(ajax校验返回及自定义返回)
TP3.2.3的验证码也是比较经典的小功能,框架对这个小功能的封装还是比较完美的,废话不多说,开始记录 1.总体效果: (1)初始界面 (2)自定义的返回校验效果: (3)ajax的校验返回: 2.代 ...
- IIS7.5配置自动添加www 及 限制通过IP访问web
IIS7.5配置自动添加www 方法 新建一个站点2(主机名为不带www的站点),将其重定向至带www的URL即可. 注意以下几点 站点2不可与站点1的路径一致,否则会导致站点1也会添加同样的重定向, ...
- bit Byte KB MB GB TB 单位换算
1TB = 1024G 1G = 1024M 1M = 1024K 1K = 1024 byte 1 byte = 8 bit
- 为PyCharm添加不同解释器
正常大家会使用Python官网的安装包,即Python.由于自己尝试了下IronPython,但打开PyCharm查看配置,发现并没有IronPython的解释器,这个需要自己加进去,如图: &quo ...
- BZOJ 2502: 清理雪道
BZOJ 2502: 清理雪道 标签(空格分隔): OI-BZOJ OI-最小流 OI-上下界网络流 Time Limit: 10 Sec Memory Limit: 128 MB Descripti ...
- 复习C++_基础、函数、数组、字符串
程序的开发过程 程序 源程序:用源语言写的,有待翻译的程序: 目标程序:源程序通过翻译程序加工以后生成的机器语言程序: 可执行程序:连接目标程序以及库中的某些文件,生成的一个可执行文件,例如Windo ...