_xiaobai_

导航

zoj1985 Largest Rectangle in a Histogram(DP)

/*
分析: 遍历每个木块,如果计算出左边和右边第一块小于当前的值的木块,
  就可求出最大面积了 O(N*max(find(L),find(R)))
  如果暴力的话,则find 为O(N) ,则O(N*N) 无法处理100000数据量。
  但是可用单调队列,做预处理 用O(N) 时间计算出所有点的边界。
  此时时间复杂度为 O(N)。
  每个元素从单调队列中出去的时间就是找到第一个不符合条件的点的时候,
  两边用0标记作为边界值。
*/

View Code
 1 #include <stdio.h>
2 #include <stdlib.h>
3
4 long long stick[ 100005 ];
5 int MUQ[ 100005 ];
6 int L[ 100005 ],R[ 100005 ];
7
8 int main()
9 {
10 int n;
11 while ( scanf("%d",&n) && n ) {
12 for ( int i = 1 ; i <= n ; ++ i )
13 scanf("%lld",&stick[ i ]);
14 stick[ 0 ] = -1; stick[ n+1 ] = -1;
15
16 /* 单调队列预处理,求出每个stick的右边的第一个小于他高度的stick位置 */
17 int tail = 0;
18 MUQ[ 0 ] = 0;
19 for ( int i = 1 ; i <= n+1 ; ++ i ) {
20 while ( tail >= 0 && stick[ MUQ[ tail ] ] > stick[ i ] )
21 R[ MUQ[ tail -- ] ] = i;
22 MUQ[ ++ tail ] = i;
23 }
24
25 /* 单调队列预处理,求出每个stick的左边的第一个小于他高度的stick位置 */
26 tail = 0;
27 MUQ[ 0 ] = n+1;
28 for ( int i = n ; i >= 0 ; -- i ) {
29 while ( tail >= 0 && stick[ MUQ[ tail ] ] > stick[ i ] )
30 L[ MUQ[ tail -- ] ] = i;
31 MUQ[ ++ tail ] = i;
32 }
33
34 long long Max = 0,Temp = 0;
35 for ( int i = 1 ; i <= n ; ++ i ) {
36 Temp = stick[ i ]*(R[ i ]-L[ i ]-1);
37 if ( Max < Temp )
38 Max = Temp;
39 }
40 printf("%lld\n",Max);
41 }
42 return 0;
43 }

posted on 2011-08-17 13:27  _xiaobai_  阅读(287)  评论(0编辑  收藏  举报