G - 秋实大哥去打工

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

天行健,君子以自强不息。地势坤,君子以厚德载物。

天天过节的秋实大哥又要过节了,于是他要给心爱的妹子买礼物。但由于最近秋实大哥手头拮据,身为一个男人,他决定去打工!

秋实大哥来到一家广告公司。现在有n块矩形墙从左至右紧密排列,每一块高为Hi,宽为Wi

公司要求秋实大哥找出一块最大的连续矩形区域,使得公司可以在上面贴出最大的海报。

Input

第一行包含一个整数n,表示矩形墙的个数。

接下来n行,每行有两个整数WiHi,表示第i块墙的宽度和高度。

1n200000,保证WiHi以及最后的答案<231

Output

最大的连续矩形的面积。

Sample input and output

Sample InputSample Output
3
3 4
1 2
3 4
14

 

解题报告

关键是找到某个元素所能扩展到的最远位置,我们维护一个单调栈即可,扫描一遍,若该元素大于栈顶元素则入栈,若小于则出栈并更新答案,注意可能一直单调递增,可在最后加一个高度为0的虚矩形,保证扫描结束后所有合法矩形已经全部出栈.

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cstdio>
 5 typedef long long ll;
 6 using namespace std;
 7 const int maxn = 2e5 + 50;
 8 int h[maxn],w[maxn],sum[maxn],s[maxn],pos[maxn];
 9 
10 int main(int argc,char *argv[])
11 {
12   int n;
13   scanf("%d",&n);
14   for(int i = 1 ; i <= n ; ++ i)
15    scanf("%d%d",&w[i],&h[i]);
16   sum[0] = 0;
17   h[n+1] = 0;
18   for(int i = 1 ; i <= n ; ++ i)
19    sum[i] = sum[i-1] + w[i];
20   int top = 0 , ans = 0 ;
21   for(int i = 1 ; i <= n+1 ; ++ i)
22    {
23          if (top > 0 && h[i] < s[top-1])
24           {
25                 while(top > 0 && h[i] < s[top-1])
26                  ans = max(ans , (sum[i-1] - sum[pos[--top]-1])*s[top]);
27           s[top++] = h[i];
28        }
29       else
30        {
31              pos[top] = i;
32              s[top++] = h[i];
33        }
34    }
35   printf("%d\n",ans);
36   return 0;
37 }

 

 

posted on 2015-05-01 01:28  天心散人  阅读(192)  评论(0编辑  收藏  举报