Largest Rectangle in a Histogram
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 21306 | Accepted: 6865 |
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.
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
n integers
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 0
Sample Output
84000
这真的是一道非常非常好的题,网上很多人说这是一道DP题,但我看到的DP的代码和利用堆栈的代码差不多,也就是说,这道题利用
堆栈其实他的核心思想和DP的做法类似,那么这符合一道DP题的特征吗。DP题一般具有以下三个特征:1:最优化原理;2:无后效性
3:有重叠子问题。DP这个解决问题的思想之所以在解决这类问题时很有优势就在于有重叠子问题这一点。那么看完这三个特征,我们
来对这道题一一对号入座。1:最优化原理,额,这个恕我直言,很难对接起来,2:无后效性,这个可以。3:有重叠子问题,额,恕我直言
以我目前的水平看不出来。所以似乎只符合一条,所以以我目前的水平来看,这似乎不是一道DP题,而是一道巧妙地解题思维题。
这道题再次告诉我:你所认为的打死都不会是O(n)复杂度的东西,在巧妙的解题方法面前就是O(1)。
#include<iostream> #include<stdio.h> using namespace std; int n; int a[100001]; int L[100001]; int R[100001]; long long ans; void solve() { int i,j; int stack[100001]; int t=0; for(i=0;i<n;i++) { while(t>0 && a[stack[t-1]]>=a[i]) t--; L[i]= (t==0)?0 : (stack[t-1]+1); stack[t++]=i; } t=0; for(i=n-1;i>=0;i--) { while(t>0 && a[stack[t-1]]>=a[i]) t--; R[i]= (t==0)?n : (stack[t-1]); stack[t++]=i; } for(i=0;i<n;i++) { ans=max(ans,(long long)a[i]*(R[i]-L[i])); } printf("%lld\n",ans); } int main() { while(~scanf("%d",&n) && n) { int i,j; for(i=0;i<n;i++) scanf("%d",&a[i]); ans=0; solve(); } return 0; }