Largest Rectangle in a Histogram(直方图中的最大矩形面积)——FOJ2559

题目:http://poj.org/problem?id=2559

想法:WA了好多次,终于AC了。错误原因:1.s=(long long)b[l-1].h*b[l-1].w;要强制转换,因为h,w都是int型,而s是long long型,这个错误最后才找到。

                                                                      2.矩形延伸变化,思路不清楚。       

做法:看了大神的这个思路,膜拜了。算法叫 单调栈
我复述一遍步骤吧,以2 1 4 5 1 3 3 为例。
首先定义结构体(h,w),h表示矩形的高度,w表示矩形的宽度。题目相当于从左到右给出宽度为1的矩形,求组成的最大的矩形面积。
1.栈空,(2,1)直接入栈。
2.(1,1,)准备入栈时,发现高度比栈顶(2,1)的h小,则矩形不能延续到(1,1)这个矩形,栈顶矩形,找出栈内现存的矩形,并计算面积、更新最大面积,面积s=2*1=2,更新最大面积max=2;
3.(2,1)出栈,此时栈空,(1,1)入栈前,变化为(1,1+1),即(1,2),再入栈(因为之间出栈的矩形(2,1),可以被现在要入栈的矩形(1,1)延伸为(1,2)这个大一点的矩形。)
4.(4,1)比栈顶(2,1)高,入栈,同理(5,1)入栈。
5.(1,1)高度小于栈顶(5,1),不可入栈。
6.将比(1,1)高的矩形(5,1)、(4,1)依次出栈。每个(h,w)出栈前,找出栈内现存的矩形,并计算面积、更新最大面积,s=5*1=5.max=5,(5,1)出栈;此时栈顶(4,1)更新为(4,1+1),(4,1)矩形向后延伸变大成大矩形(4,2),s=4*2=8,max=8,
(4,2)出栈。(为什么(4,2)可以直接更新?因为它一定可以往后延伸,而延伸出来的矩形一定比它本身大)
7.(1,1)该入栈了,入栈之前,它应该更新为(1,1+2),这里面的二是(4,2)里面的2,也就是最后出栈的那个矩形的宽度,因为(4,2)这个矩形可以变成(1,2)延伸过来和(1,1)构成(1,3)这个大一点的矩形。
8.更新好后由于要入栈的(1,3)和当前栈顶(1,3)h一样,这时就不用入栈了,把栈顶(1,3)更新为(1,3+2)即(1,5),即可,因为就相当于矩形变大了。
9.(1,3)比(1,4)高,入栈。
10.(1,3)与当前栈顶(1,3)一样高,栈顶更新为(3,1+1)即可。
11.(0,1)准备入栈(为了将前面的矩形全部出栈),将栈内(3,2)、(1,5)依次出栈,(3,2)准备出栈,s=3*2,max=8,(1,4),更新为(1,5+2),(3,2)出栈;(1,7)准备出栈,s=1*7=7。
12.(0,1)入栈,结束操作。

代码:

 1 #include <stdio.h>
 2 struct node
 3 {
 4     int h,w;
 5 } a[100005],b[100005];
 6 long long max,s;
 7 int main()
 8 {
 9     int i,n,l;//栈中元素个数l
10     freopen("1.txt","r",stdin);
11     while(~scanf("%d",&n)&&n)
12     {
13         max=0;
14         l=0;
15         for(i=0; i<n; i++)
16         {
17             scanf("%d",&a[i].h);//输入
18             a[i].w=1;//初始化
19         }
20         a[n].h=0;
21         a[n].w=1;
22         for(i=0; i<=n; i++) //最后(0,1)入栈前,所有元素都出栈了
23         {
24             if(l==0||a[i].h>b[l-1].h) //如果栈空、或准备入栈的矩形h>栈顶h,矩形可延续,直接入栈
25             {
26                 b[l].h=a[i].h;
27                 b[l].w=a[i].w;
28                 l++;//长度加一
29             }
30             else if(a[i].h==b[l-1].h) //如果准备入栈的矩形h=栈顶h,矩形可延续,直接更新栈顶矩形w即可
31             {
32                 b[l-1].w=b[l-1].w+a[i].w;
33             }
34             else //如果准备入栈的矩形h<栈顶h,矩形不可延续,要出栈
35             {
36                 s=(long long)b[l-1].h*b[l-1].w;//栈顶矩形的面积
37                 //printf("s=%lld\n",s);
38                 max=(s>max)?s:max;//更新面积最大值
39                 l--;//出栈
40                 if(l&&a[i].h<b[l-1].h)//表示将会继续出栈
41                     b[l-1].w=b[l-1].w+b[l].w;//更新栈顶元素,栈顶矩形变化延伸(当前栈顶矩形宽度加宽,加上原先栈顶宽度)
42                 else
43                     a[i].w=a[i].w+b[l].w;//准备入栈的矩形宽度加宽,加上出栈的矩形的宽度
44                 i--;
45             }
46         }
47         printf("%lld\n",max);
48     }
49     return 0;
50 }

猜你喜欢

转载自www.cnblogs.com/li-yaoyao/p/9498242.html
今日推荐