1. 程式人生 > 實用技巧 >[POI2008]PLA-Postering

[POI2008]PLA-Postering

題目連結

[POI2008]PLA-Postering

description

春春幼兒園升級版

solution

此題資料較強,於是我們可以用單調棧來維護.具體維護方式如下:

首先將\(ans\)初始化為\(n\),對於當前高度\(h\),如果當前棧頂大於\(h\),則將棧頂彈出,直到棧頂不大於\(h\)或棧空.進行此番操作後,將棧頂元素與\(h\)比較,若相等則\(--ans\).然後將當前元素入棧即可.

正確性證明:(大眼觀察法)我們容易發現,寬度是無關變數,答案只與高度有關.而且,\(n\)是肯定滿足答案的,所以我們可以從\(n\)開始考慮.欲省掉一張海報,當且僅當兩值之間的值均大於此二值且此二值相等,所以可以用單調棧維護.

code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#define R register
#define next jkflsdlkf
#define debug puts("mlg")
#define mod 10007
#define Mod(x) ((x%mod+mod)%mod)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
inline ll read();
inline void write(ll x);
inline void writesp(ll x);
inline void writeln(ll x);
ll n,_stack[1000000],t,ans;
int main(){
	ans=n=read();
	for(R ll i=1,h;i<=n;i++){
		read();h=read();
		while(t&&_stack[t]>h) t--;
		if(_stack[t]==h) --ans;
		_stack[++t]=h;
	}
	writeln(ans);
} 
inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
inline void writesp(ll x){write(x);putchar(' ');}
inline void writeln(ll x){write(x);putchar('\n');}