单调栈(两边扩展)
http://acm.hdu.edu.cn/showproblem.php?pid=1506
题意:给出连续的一组宽度为1,高为a[i]的长方形 , 问整个图所能构成的面积最大的长方形。
解法:单调递增栈记录以每一个值为最小值的两边扩展的最大值。比较以每一个值为最小值组成长方形面积的最大值。
//#include<bits/stdc++.h> #include<iostream> #include<stdio.h> #include<cstring> #include<cmath> using namespace std ; typedef long long ll ; const int N = 100010, M = 200010 ; int a[N] ; ll len[N];//以i为最小值,当前i所能向左向右扩展的最小值 int st[N] , top ; int n ; void solve(){ for(int i = 0 ; i < n ; i++){ scanf("%d" , &a[i]); len[i] = 1 ; } top = 0 ; int cnt = 0 ; for(int i = 0 ; i < n ; i++){ cnt = 0 ;//当前右边扩展长度 while(top && a[st[top]] >= a[i]){ len[st[top]] += cnt ;//我被弹(扩展右边) cnt = len[st[top]] ; top-- ; } len[i] += cnt ;//我弹别人(扩展左边) st[++top] = i ; } cnt = 0 ; while(top){ len[st[top]] += cnt ; cnt = len[st[top]] ; top-- ; } ll ans = 0 ; for(int i = 0 ; i < n ; i++){ ans = max(ans , len[i]*a[i]); } cout << ans << endl; } signed main(){ #ifdef ONLINE_JUDGE #else freopen("D:\\c++\\in.txt", "r", stdin); //freopen("D:\\c++\\out.txt", "w", stdout); #endif while(~scanf("%d" , &n) && n) solve(); }