題目連接:http://acm.hdu.edu.cn/showproblem.php?pid=1506php
題目的意思其實就是要找到一個儘量大的矩形來徹底覆蓋這個矩形下的全部柱子,只能覆蓋柱子,不能留空。node
咱們求得的面積其實就是Max{s=(right[i] - left[i] + 1)*height[i];(i>=1&&i<=n)}ios
每個柱子都要儘量向左向右延伸,使得得到最大的面積。spa
此時我就要用到單調棧.net
單調棧就是棧內元素單調遞增或者單調遞減的棧,單調棧只能在棧頂操做。code
http://blog.csdn.net/liujian20150808/article/details/50752861blog
這裏咱們仍是作一個總結ci
單調棧的維護是 O(n) 級的時間複雜度,由於全部元素只會進入棧一次,而且出棧後不再會進棧了。rem
單調棧的性質:get
1.單調棧裏的元素具備單調性
2.元素加入棧前,會在棧頂端把破壞棧單調性的元素都刪除
3.使用單調棧能夠找到元素向左遍歷第一個比他小的元素,也能夠找到元素向左遍歷第一個比他大的元素。
基於此題,咱們能夠知道,先每一次從左到右放入柱子(保持遞增單調棧),也就說一旦有一個柱子和棧頂元素一比發現比它大,那麼這個柱子首先要記錄它的left值爲本身的自己的下標,若是發現這個柱子比棧頂的小,咱們依次將棧頂元素出棧,直至又能組成遞增的序列,此時這個柱子的left值就爲如今棧頂的left值。
後面咱們從右向左放入柱子(保持的依舊是遞增的單調棧)。得到right值。
代碼以下
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<stack> 5 #define LL long long 6 using namespace std; 7 const int MAXN = 100005; 8 struct node 9 { 10 LL height; 11 int left; 12 int right; 13 int index; 14 }; 15 node nd[MAXN]; 16 int n; 17 stack <node> st;//定義一個單調棧 18 void clr() 19 { 20 while(!st.empty()) 21 st.pop(); 22 } 23 LL work() 24 { 25 clr(); 26 for(int i = 1;i<=n;i++) 27 { 28 if(st.empty()) 29 { 30 nd[i].left = i; 31 st.push(nd[i]); 32 } 33 else 34 { 35 node td = st.top(); 36 if(td.height<nd[i].height) 37 { 38 nd[i].left = i; 39 st.push(nd[i]); 40 } 41 else 42 { 43 bool flag=false; 44 int c; 45 while(!st.empty()) 46 { 47 if((st.top()).height>=nd[i].height) 48 { 49 c = (st.top()).left; 50 st.pop(); 51 } 52 else 53 { 54 nd[i].left = c; 55 flag =true; 56 st.push(nd[i]); 57 break; 58 } 59 } 60 if(flag == false) 61 { 62 nd[i].left = c; 63 st.push(nd[i]); 64 } 65 } 66 } 67 } 68 clr(); 69 for(int i = n;i>=1;i--) 70 { 71 if(st.empty()) 72 { 73 nd[i].right = i; 74 st.push(nd[i]); 75 } 76 else 77 { 78 node td = st.top(); 79 if(td.height<nd[i].height) 80 { 81 nd[i].right = i; 82 st.push(nd[i]); 83 } 84 else 85 { 86 bool flag=false; 87 int c; 88 while(!st.empty()) 89 { 90 if((st.top()).height>=nd[i].height) 91 { 92 c = (st.top()).right; 93 st.pop(); 94 } 95 else 96 { 97 nd[i].right = c; 98 st.push(nd[i]); 99 flag = true; 100 break; 101 } 102 } 103 if(flag == false) 104 { 105 nd[i].right = c; 106 st.push(nd[i]); 107 } 108 } 109 } 110 } 111 LL maxs = 0; 112 LL s; 113 for(int i = 1;i<=n;i++) 114 { 115 s = (nd[i].right - nd[i].left + 1)*nd[i].height; 116 if(maxs<s) 117 maxs = s; 118 } 119 return maxs; 120 } 121 int main() 122 { 123 while(~scanf("%d",&n)) 124 { 125 if(n==0) 126 break; 127 for(int i = 1;i<=n;i++) 128 { 129 nd[i].index = i; 130 scanf("%I64d",&nd[i].height); 131 } 132 cout<<work()<<endl; 133 } 134 return 0; 135 }