2015 UESTC 数据结构专题G题 秋实大哥去打工 单调栈

秋实大哥去打工

Time Limit: 1 Sec  Memory Limit: 256 MB

题目连接

http://acm.uestc.edu.cn/#/contest/show/59

Description



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

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

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

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

Input

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

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

1≤n≤200000,保证Wi,Hi以及最后的答案<231。

Output

最大的连续矩形的面积。

Sample Input

3
3 4
1 2
3 4

Sample Output

14

HINT


题意


题解:

初看这道题,啊好难啊
其实仔细思考一下很简单的
首先我们离散化一下下,然后我们再随便搞一搞
用两个单调栈维护以这个矩形为高最多往左和右延伸多少~
然后随便搞一搞就好了

代码:

 

//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 200001
#define mod 10007
#define eps 1e-9
//const int inf=0x7fffffff;   //无限大
const int inf=0x3f3f3f3f;
/*
inline ll read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int buf[10];
inline void write(int i) {
  int p = 0;if(i == 0) p++;
  else while(i) {buf[p++] = i % 10;i /= 10;}
  for(int j = p-1; j >=0; j--) putchar('0' + buf[j]);
  printf("\n");
}
*/
//**************************************************************************************
using namespace std;
long long a[maxn],b[maxn],ans;
int r[maxn],l[maxn];
stack<int> s;
int main()
{
    int n;
    scanf("%d",&n);
    a[0]=a[n+1]=-1;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&b[i]);
        b[i]+=b[i-1];
        scanf("%lld",&a[i]);
    }
    s.push(0);
    int p=0;
    for(int i=1;i<=n;i++)
    {
        for(p=s.top();a[p]>=a[i];p=s.top())
            s.pop();
        l[i]=p+1;
        s.push(i);
    }
    while(!s.empty())
        s.pop();
    s.push(n+1);
    for(int i=n;i>0;i--)
    {
        for(p=s.top();a[p]>=a[i];p=s.top())
            s.pop();
        r[i]=p-1;
        s.push(i);
    }
    for(int i=1;i<=n;i++)
        ans=max(ans,((b[r[i]]-b[i-1])+(b[i-1]-b[l[i]-1]))*a[i]);
    printf("%lld\n",ans);
    return 0;
}

 

posted @ 2015-04-14 23:15  qscqesze  阅读(232)  评论(0编辑  收藏  举报