【洛谷3467/BZOJ1113】[POI2008]海报PLA-Postering(单调栈)
题目:
洛谷3467
分析:
(ti jie shuo)这题是个单调栈经典题。
单调栈就是栈元素递增或递减的栈,这里只考虑递增。新元素入递增栈时,先将所有比它大的元素弹出,然后让新元素入栈,这样保证栈顶永远是最大的元素,代码如下:(\(a\)是新元素)
while(top>0&&stack[top]>a)top--;
stack[++top]=a;
然后来分析这道题。我这种蒟蒻乍一看一脸懵逼,但是可以注意到这样一个事实:
如果先让每个楼都贴一张海报(\(ans=n\)),如果两栋高度相同的楼之间没有比它们矮的楼,这两座楼就可以用一张海报覆盖(\(ans\)--),而中间那些比它们高的楼仍然每个楼需要一张海报。如下图(然而如果两栋楼之间有一栋比它们低的楼就不可以,因为题目要求海报不能超出建筑物)
然后这个题就很简单了,对于每一座楼都把栈里比他高的弹出去,然后如果此时栈顶跟它一样,就说明两栋楼可以用一张海报。
(由于这座楼的限制,后面比它高的楼都不能和这座楼前面比它高的楼公用海报,所以要弹出)
代码:
#include<algorithm>
#include<cstdio>
using namespace std;
int n,stack[250010],top,trash,ans;
int main(void)
{
scanf("%d",&n);
scanf("%d%d",&trash,&stack[0]);
ans=n;
for(int i=1;i<n;i++)
{
int a;
scanf("%d%d",&trash,&a);
while(top>0&&stack[top]>a)top--;
if(a==stack[top])ans--;
else stack[++top]=a;
}
printf("%d",ans);
return 0;
}