P3467 [POI2008]PLA-Postering 题解
这道题首先可以发现,宽度是完全没有用处的,所以可以忽略不计。
然后在贴海报时,可以发现:如果某一个点与前面某一个点相同,而且这两个点中间没有比他们低的点,那么可以节省一张海报。
啥意思?比如说:
1 4 2 1 2 3
处理时,由于两个 1 中间没有比 1 低的,那么他们可以共享一张海报(使用公共边),而两个 2 之间就不行,因为里面有一个搞事情的 1 ,使得两个 2 不能共用一张海报。
而此时问题就变成了如何处理两个 2 中间的 1 ?其实当出现了一个 1 的时候,前面的所有比 1 大的数全部没有用处了,而这个操作恰好可以使用单调栈维护。
我们维护一个单调递增栈,栈内元素单调递增,加入新数据时弹栈完毕后只需要判断一下当前栈顶元素是否与加入元素相等就可以了,如果是相等的,不需要新增一张海报,否则需要新增一张海报。
代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=250000+10;
int n,h[MAXN],p,ans,sta[MAXN];
int read()
{
int sum=0,fh=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') fh=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return sum*fh;
}
int main()
{
n=read();
for(int i=1;i<=n;i++) {read();h[i]=read();}
p=0;
for(int i=1;i<=n;i++)
{
ans++;
while(p!=0&&h[sta[p]]>h[i]) p--;
if(h[sta[p]]==h[i]) ans--;
sta[++p]=i;
}
cout<<ans<<"\n";
return 0;
}