HDU1506 Largest Rectangle in a Histogram(算競進階習題)
阿新 • • 發佈:2019-03-12
面積 習題 inf 所有 getchar 需要 def 因此 最大
單調棧裸體
如果矩形高度從左到右是依次遞增,那我們枚舉每個矩形高度,寬度拉到最優,計算最大面積即可
當有某個矩形比前一個矩形要矮的時候,這塊面積的高度就不能大於他本身,所以之前的所有高於他的矩形多出來的部分都沒用了,不會再計算第二次。
因此我們只需要用單調棧維護矩形高度即可,當有高度較低的矩形進棧時,先將之前比他高的每個矩形彈出,寬度累加,更新答案。然後我們要進棧的矩形的寬度也要變成之前累加的寬度+1,因為要保留有用部分。。
有個小技巧:為了方便程序,在末尾加一個高度為0的矩形
#include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; inline int lowbit(int x){ return x & (-x); } inline int read(){ int X = 0, w = 0; char ch = 0; while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); } while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar(); return w ? -X : X; } inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; } inline int lcm(int a, int b){ return a / gcd(a, b) * b; } template<typename T> inline T max(T x, T y, T z){ return max(max(x, y), z); } template<typename T> inline T min(T x, T y, T z){ return min(min(x, y), z); } template<typename A, typename B, typename C> inline A fpow(A x, B p, C yql){ A ans = 1; for(; p; p >>= 1, x = 1LL * x * x % yql)if(p & 1)ans = 1LL * x * ans % yql; return ans; } ll h[100005], s[100005], w[100005], tot; int main(){ int n; while(cin >> n && n){ memset(h, 0, sizeof h); memset(s, 0, sizeof s); memset(w, 0, sizeof w); ll ans = 0; w[n + 1] = 0; tot = 0; for(int i = 1; i <= n; i ++) cin >> h[i]; for(int i = 1; i <= n + 1; i ++){ if(s[tot] > h[i]){ ll width = 0; while(tot > 0 && s[tot] > h[i]){ width += w[tot]; ans = max(ans, (ll)width * s[tot]); tot --; } s[++tot] = h[i], w[tot] = width + 1; } else{ s[++tot] = h[i], w[tot] = 1; } } printf("%lld\n", ans); } return 0; }
HDU1506 Largest Rectangle in a Histogram(算競進階習題)