POJ 2559 Largest Rectangle in a Histogram (单调栈或者dp)
Largest Rectangle in a Histogram
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15831 Accepted: 5121 Description
A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles:
Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.Input
The input contains several test cases. Each test case describes a histogram and starts with an integer n, denoting the number of rectangles it is composed of. You may assume that 1<=n<=100000. Then follow nintegers h1,...,hn, where 0<=hi<=1000000000. These numbers denote the heights of the rectangles of the histogram in left-to-right order. The width of each rectangle is 1. A zero follows the input for the last test case.Output
For each test case output on a single line the area of the largest rectangle in the specified histogram. Remember that this rectangle must be aligned at the common base line.Sample Input
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0Sample Output
8
4000Hint
Huge input, scanf is recommended.Source
/*************************************************************************
> File Name: poj_2559.cpp
> Author: Howe_Young
> Mail: 1013410795@qq.com
> Created Time: 2015年04月08日 星期三 09时00分34秒
************************************************************************/ #include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <cstdio>
#define INF 99999999999999
using namespace std;
typedef long long LL;
const int N = ;
LL h[N], l[N], r[N];
LL Max(LL a, LL b)
{
return a > b ? a : b;
}
int main()
{
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
int n;
while (~scanf("%d", &n) && n)
{
memset(l, , sizeof(l));
memset(r, , sizeof(r));
for (int i = ; i <= n; i++)
scanf("%lld", &h[i]);
l[] = ; h[] = -;
r[n] = n + ; h[n + ] = -;
for (int i = ; i <= n; i++)//找左边元素
{
if (h[i] < h[i - ])
{
int tmp = l[i - ];
while (h[i] <= h[tmp])//动态规划方法找,如果不用这中方法,普通的tmp--找的话会超时
tmp = l[tmp];
l[i] = tmp;
}
else if (h[i] == h[i - ])
l[i] = l[i - ];
else
l[i] = i - ;
}
for (int i = n - ; i > ; i--)//找右边
{
if (h[i] < h[i + ])
{
int tmp = r[i + ];
while (h[i] <= h[tmp])
tmp = r[tmp];
r[i] = tmp;
}
else if (h[i] == h[i + ])
r[i] = r[i + ];
else
r[i] = i + ;
}
LL ans = -;
for (int i = ; i <= n; i++)
{
h[i] = (r[i] - l[i] - ) * h[i];
ans = Max(ans, h[i]);
}
printf("%lld\n", ans);
}
return ;
}
单调栈的思路是将这些柱子分别一个一个的判断,如果大于前面的那个那么前面比他大的就是0, 所以直接压栈,如果小于的话,弹栈,知道弹出小于它的为止,等于它,弹出来一个,压进去一个。
代码二(单调栈):
/*************************************************************************
> File Name: poj_2559_stack.cpp
> Author: Howe_Young
> Mail: 1013410795@qq.com
> Created Time: 2015年04月08日 星期三 09时48分09秒
************************************************************************/ #include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <cstdio>
#include <stack>
using namespace std;
typedef long long LL;
const int N = ;
LL h[N], r[N], l[N];
LL Max(LL a, LL b)
{
return a > b ? a : b;
}
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int n;
while (~scanf("%d", &n) && n)
{
memset(l, , sizeof(l));
memset(r, , sizeof(r));
for (int i = ; i <= n; i++)
scanf("%lld", &h[i]);
stack<int> S;//找出左边的元素比他大的或者等于它的个数,单调栈
S.push();//把额外的一个点压进去,防止栈弹空
h[] = h[n + ] = -;
for (int i = ; i <= n; i++)
{
if (h[i] < h[i - ])//如果后者比前者小
{
int cnt = ;
while (h[S.top()] >= h[i])
{
l[i] += l[S.top()] + ;
S.pop();
}
S.push(i);
}
else if (h[i] == h[i - ])
{
S.pop();
S.push(i);
l[i] = l[i - ] + ;
}
else
{
l[i] = ;
S.push(i);
}
}
stack<int> S2;//找处右边大于等于它的个数
S2.push(n + );
for (int i = n; i > ; i--)
{
if (h[i] < h[i + ])
{
int cnt = ;
while (h[S2.top()] >= h[i])
{
r[i] += r[S2.top()] + ;
S2.pop();
}
S2.push(i);
}
else if (h[i] == h[i + ])
{
S2.pop();
S2.push(i);
r[i] = r[i + ] + ;
}
else
{
S2.push(i);
r[i] = ;
}
}
LL ans = -;
for (int i = ; i <= n; i++)
{
h[i] *= (l[i] + r[i] + );
ans = Max(ans, h[i]);
}
printf("%lld\n", ans); }
return ;
}
过了一段时间又做了一遍。感觉代码比上面两个要好一点
代码三(单调栈):
/*************************************************************************
> File Name: largest.cpp
> Author: Howe_Young
> Mail: 1013410795@qq.com
> Created Time: 2015年09月10日 星期四 18时54分01秒
************************************************************************/ #include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm> using namespace std;
typedef long long ll;
const int maxn = ;
int a[maxn];
int L[maxn], R[maxn];
int stack[maxn];//单调递增栈
int main()
{
int n;
while (~scanf("%d", &n) && n)
{
for (int i = ; i <= n; i++)
scanf("%d", &a[i]);
a[] = a[n + ] = -;//添加两个端点位置
int top = ;
stack[++top] = ;
for (int i = ; i <= n; i++)//求出左边做远能扩展到的位置
{
if (a[i] > a[i - ])
{
L[i] = i;
stack[++top] = i;
}
else
{
while (a[stack[top]] >= a[i]) top--;
L[i] = L[stack[top + ]];
stack[++top] = i;
}
}
top = ;
stack[++top] = n + ;
for (int i = n; i >= ; i--)//右边
{
if (a[i] > a[i + ])
{
R[i] = i;
stack[++top] = i;
}
else
{
while (a[stack[top]] >= a[i]) top--;
R[i] = R[stack[top + ]];
stack[++top] = i;
}
}
long long ans = ;
for (int i = ; i <= n; i++)
ans = max(ans, (long long)a[i] * (R[i] - L[i] + ));
printf("%lld\n", ans);
}
return ;
}
POJ 2559 Largest Rectangle in a Histogram (单调栈或者dp)的更多相关文章
- poj 2559 Largest Rectangle in a Histogram - 单调栈
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19782 ...
- POJ 2559 Largest Rectangle in a Histogram(单调栈)
传送门 Description A histogram is a polygon composed of a sequence of rectangles aligned at a common ba ...
- PKU 2559 Largest Rectangle in a Histogram(单调栈)
题目大意:原题链接 一排紧密相连的矩形,求能构成的最大矩形面积. 为了防止栈为空,所以提前加入元素(-1,0) #include<cstdio> #include<stack> ...
- [POJ 2559]Largest Rectangle in a Histogram 题解(单调栈)
[POJ 2559]Largest Rectangle in a Histogram Description A histogram is a polygon composed of a sequen ...
- stack(数组模拟) POJ 2559 Largest Rectangle in a Histogram
题目传送门 /* 题意:宽度为1,高度不等,求最大矩形面积 stack(数组模拟):对于每个a[i]有L[i],R[i]坐标位置 表示a[L[i]] < a[i] < a[R[i]] 的极 ...
- poj 2559 Largest Rectangle in a Histogram 栈
// poj 2559 Largest Rectangle in a Histogram 栈 // // n个矩形排在一块,不同的高度,让你求最大的矩形的面积(矩形紧挨在一起) // // 这道题用的 ...
- poj 2559 Largest Rectangle in a Histogram (单调栈)
http://poj.org/problem?id=2559 Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 6 ...
- POJ2559 Largest Rectangle in a Histogram —— 单调栈
题目链接:http://poj.org/problem?id=2559 Largest Rectangle in a Histogram Time Limit: 1000MS Memory Lim ...
- 题解报告:poj 2559 Largest Rectangle in a Histogram(单调栈)
Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base l ...
随机推荐
- C++函数重载遇到了函数默认参数情况
一.C++中的函数重载 什么是函数重载? 我的理解是: (1)用一个函数名定义不同的函数: (2)函数名和不同参数搭配时函数会有不同的含义: 举例说明: #include <stdio.h> ...
- 01:A+B问题
总时间限制: 1000ms 内存限制: 65536kB 描述 在大部分的在线题库中,都会将A+B问题作为第一题,以帮助新手熟悉平台的使用方法. A+B问题的题目描述如下:给定两个整数A和B,输出A ...
- [BZOJ 1875] [SDOI 2009] HH去散步【矩阵乘法】
题目链接:BZOJ - 1875 题目分析: 这道题如果去掉“不会立刻沿着刚刚走来的路走回”的限制,直接用邻接矩阵跑矩阵乘法就可以了.然而现在加了这个限制,建图的方式就要做一些改变.如果我们把每一条边 ...
- NYOJ 540
为了给学弟学妹讲课,我水了一道题…… import java.util.Arrays; import java.util.Scanner; public class NYOJ540 { public ...
- 教你在Java的普通类中轻松获取Session以及request中保存的值
曾经有多少人因为不知如何在业务类中获取自己在Action或页面上保存在Session中值,当然也包括我,但是本人已经学到一种办法可以解决这个问题,来分享下,希望对你有多多少少的帮助! 如何在Java的 ...
- js/jquery/插件表单验证
媳妇要学js,就收集一些资料给她. 1.js 表单验证 : http://hi.baidu.com/yanchao0901/item/161f563fb84ea5433075a1eb 2.jquery ...
- h.264直接预测
直接预测是B帧上一种独有的预测方式,其中直接预测又分为两种模式: 时域直接模式(temporal direct).空域直接模式(spatial direct). 在分析这两种模式之前,有一个前提概念需 ...
- SIM卡基础知识
一:了解Sim卡和GSM网络登录步骤的基本知识 (一)名词解释: SIM卡(Subscriber Identity Module),即用户识别卡,它是一张符合GSM规范的“智慧卡”,SIM卡有大小之分 ...
- Delphi控件的透明与不透明(要挨个解释一下原因),对InvalidateControl的关键理解
procedure TForm1.Button3Click(Sender: TObject);begin if (csOpaque in ControlStyle) then ShowMessage( ...
- 权重随机算法的java实现
一.概述 平时,经常会遇到权重随机算法,从不同权重的N个元素中随机选择一个,并使得总体选择结果是按照权重分布的.如广告投放.负载均衡等. 如有4个元素A.B.C.D,权重分别为1.2.3.4,随机结果 ...
