1. 程式人生 > >newcoder 小A的柱狀圖(單調棧)題解

newcoder 小A的柱狀圖(單調棧)題解

ive desc 表示 tdi 輸出 preview names images margin

題目描述

柱狀圖是有一些寬度相等的矩形下端對齊以後橫向排列的圖形,但是小A的柱狀圖卻不是一個規範的柱狀圖,它的每個矩形下端的寬度可以是不相同的一些整數,分別為a[i] 每個矩形的高度是h[i] ,現在小A只想知道,在這個圖形裏面包含的最大矩形面積是多少。 技術分享圖片

輸入描述:

一行一個整數N,表示長方形的個數
接下來一行N個整數表示每個長方形的寬度
接下來一行N個整數表示每個長方形的高度

輸出描述:

一行一個整數,表示最大的矩形面積
思路: 先用前綴和維護寬度。我們把寬度為a[i]想成a[i]個寬度為1的放在一起就行了。我們如果能找到某一高度的左右第一個比他小的位置,那麽就能求出以他為高的最大值。顯然直接暴力n方復雜度。那麽我們這裏可以用單調棧維護一下。我們每次對比棧頂和入棧高度hi,如果棧頂小與等於hi,那麽hi入棧,因為顯然此時我沒找到棧頂最右第一個比它小的,直到hi比棧頂小,那麽我棧頂右一就是當前的i,左一就是S[top-1]。 代碼:
#include<cmath>
#include
<set> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include <iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 1e6 + 10; const ull seed = 131; const int
INF = 0x3f3f3f3f; const int MOD = 1000000007; struct node{ ll hei; int pos; node(int p = 0, ll h = 0): pos(p), hei(h){} }s[maxn]; ll sum[maxn], h[maxn]; int n, top; ll solve(){ ll ans = 0; top = 0; for(int i = 1; i <= n; i++){ if(top == 0 || h[i] >= s[top].hei) s[++top] = node(i, h[i]);
else{ int r, l; while(top > 0 && s[top].hei > h[i]){ r = i - 1; l = (top == 1? 0 : s[top - 1].pos); ans = max(ans, s[top].hei * (sum[r] - sum[l])); --top; } s[++top] = node(i, h[i]); } } if(top > 0){ int r, l; r = s[top].pos; while(top > 0){ l = (top == 1? 0 : s[top - 1].pos); ans = max(ans, s[top].hei * (sum[r] - sum[l])); --top; } } return ans; } int main(){ scanf("%d", &n); sum[0] = 0; for(int i = 1; i <= n; i++){ scanf("%lld", &sum[i]); sum[i] += sum[i - 1]; } for(int i = 1; i <= n; i++) scanf("%lld", &h[i]); printf("%lld\n", solve()); return 0; }

newcoder 小A的柱狀圖(單調棧)題解