uestc poj2559 秋实大哥去打工

//感觉有必要把这题放博客上待复习 刚刚写解题报告的时候发现自己又不会做这题了

//我不会告诉你这题绝对是命题人抄poj2559

这题使用一个单调递增的栈,栈内存储的元素有两个值,一个高度,一个长度。

假如后一个元素的高度比栈顶元素小,那么从栈顶元素一定无法延伸到当前元素,于是乎我们就弹栈来降低栈顶的元素的高度,即把栈顶的元素和下一个元素合并,合并后高度为两者的最小值,宽度为两者加和(其实这就相当于新产生了一种方案)。进行弹栈操作直到栈顶元素小于当前元素,然后当前元素进栈。

弹栈时记录新产生的栈的元素的面积(其实就是新方案的面积),取最大值即为答案。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<string>

using namespace std;

struct rec{
    int h,w;
};

int n;
rec a[200007];
rec stk[200007];
int top;

int main(){
    memset(a,0,sizeof(a));
    memset(stk,0,sizeof(stk));
    scanf("%d",&n);
    for (int i=1;i<=n;i++){
            scanf("%d%d",&a[i].w,&a[i].h);
    }
    top=0;
    int ans=0;
    for (int i=1;i<=n;i++){
            int totw=0;
            while (top>0 && stk[top].h>a[i].h){
                    totw=totw+stk[top].w;
                    ans=max(ans,stk[top].h*totw);
                    top--;
            }
            top++;
            stk[top].w=a[i].w+totw;
            stk[top].h=a[i].h;
    }
    while (top>0){
            ans=max(ans,stk[top].h*stk[top].w);
            stk[top-1].w=stk[top-1].w+stk[top].w;
            top--;
    }
    printf("%d
",ans);
}
/*
3
3 4
1 2
3 4

3
3 2
10 3
3 3

7
1 2
1 1
1 4
1 5
1 1
1 3
1 3
*/
原文地址:https://www.cnblogs.com/baby-mouse/p/4447080.html