hdu 1506 單調棧問題

題目連接: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 }
相關文章
相關標籤/搜索