poj2082 terrible sets 单调栈

时间:2020-05-29
本文章向大家介绍poj2082 terrible sets 单调栈,主要包括poj2082 terrible sets 单调栈使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目链接:https://vjudge.net/problem/POJ-2082

题意:给定一些矩形的底边长和高,问能拼出的最大新矩形的面积

等价于求一个区间内最小高度乘底边宽度和的最大值。考虑每个矩形,向左右延伸至第一个高度小于它的矩形,记录下延伸到的前一个位置l[i]和r[i],用类似前缀和的方法求出几个连续矩形的底边宽度和。

则答案ans=max(ans,(s[r[i]]-s[l[i]-1])*a[i].h),此处s即为前缀和数组。

注意要开long long

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<stack>
 4 #include<cstring>
 5 #define ll long long
 6 using namespace std;
 7 const int maxn=500+10;
 8 
 9 struct qwq{int w,h;}a[maxn];
10 stack<int> st;
11 int l[maxn],r[maxn],s[maxn];
12 int t,n,i,j,k,m;
13 
14 void solve(){
15     memset(s,0,sizeof(s));
16     for (i=1;i<=n;i++) s[i]=s[i-1]+a[i].w;
17     st.push(1);
18     a[n+1].h=a[0].h=-1;
19     for (i=2;i<=n+1;i++){ //向右延伸 
20         while (!st.empty()&&a[st.top()].h>a[i].h){
21             r[st.top()]=i-1;
22             st.pop();    
23         }
24         st.push(i);
25     }
26     while (!st.empty()) st.pop();st.push(n);
27     for (i=n-1;i>=0;i--){ //向左延伸        
28         while (!st.empty()&&a[st.top()].h>a[i].h){
29             l[st.top()]=i+1;
30             st.pop();
31         }    
32         st.push(i);
33     }
34     ll ans=0;
35     for (i=1;i<=n;i++) { 
36         ll res=(s[r[i]]-s[l[i]-1])*a[i].h;
37         ans=max(ans,res);
38     }
39     cout<<ans<<endl;
40     while (!st.empty()) st.pop();
41 }
42 
43 int main(){
44     //freopen("poj2082.txt","r",stdin);
45     std::ios::sync_with_stdio(false);
46     cin>>n;
47     while (n!=-1) {
48         for (i=1;i<=n;i++) cin>>a[i].w>>a[i].h;
49         solve();
50         cin>>n;
51     }
52     return 0;
53 }
poj2082

原文地址:https://www.cnblogs.com/edmunds/p/12989386.html