zoukankan      html  css  js  c++  java
  • [POI 2008&洛谷P3467]PLA-Postering 题解(单调栈)

    [POI 2008&洛谷P3467]PLA-Postering

    Description

    Byteburg市东边的建筑都是以旧结构形式建造的:建筑互相紧挨着,之间没有空间.它们共同形成了一条长长的,从东向西延伸的建筑物链(建筑物的高度不一).
    Byteburg市的市长Byteasar,决定将这个建筑物链的一侧用海报覆盖住.并且想用最少的海报数量,海报是矩形的.
    海报与海报之间不能重叠,但是可以相互挨着(即它们具有公共边),每一个海报都必须贴近墙并且建筑物链的整个一侧必须被覆盖(意思是:海报需要将一侧全部覆盖,并且不能超出建筑物链)

    输入格式:第一行为一个整数n(1≤n≤250000),表示有n个建筑,接下来n行中,第i行表示第i个建筑物的宽di与高wi(1≤di,wi≤1 000 000 000),中间由一个空格隔开;

    输出格式:第一个为一个整数,表示最少需要几张海报覆盖整个建筑物.

    Solution

    1.考虑如果整个建筑物链是等高的,一张高为链高,宽为整个建筑物宽的海报即可完全覆盖;

    2.若有两个不等高的元素组成建筑物链,那么一定需要两张;

    3.因为题目要求海报不可超出建筑物链,那么我们即可用单调栈维护:初始海报数为建筑物数,入栈建筑物链的高度序列,当栈顶大于即将入栈元素时弹栈,若最后弹栈元素与即将入栈元素等高,需要的海报数-1;

    4.易证明本方法是正确的:当有两个处于一个峰两侧的等高块时,他们可以用一张海报覆盖,所需海报数显然可减少一个;

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm> 
    using namespace std;
    long long top=0,n,num=0,i,j,k,stack[250100];
    int main(){
    	scanf("%lld",&n);
    	for(i=1;i<=n;++i){
    		scanf("%lld%lld",&j,&k);
    		while(top>0&&k<=stack[top]){
    			if(k==stack[top])num++;
    			--top;
    		}
    		stack[++top]=k;
    	}
    	printf("%lld
    ",n-num);
    	return 0;
    }
    

    单调栈基础知识部分可以参考我的题解:http://www.cnblogs.com/COLIN-LIGHTNING/p/8474668.html

  • 相关阅读:
    OCS 2007 R2下载资源整理
    Windows Server 2012 R2 WSUS 4.0 加速
    JavaScript入门(三)
    JavaScript入门(一)
    JavaScript入门(二)
    CSS基础
    古董代码
    自我介绍
    Android Activity的加载的模式
    Android 数字签名
  • 原文地址:https://www.cnblogs.com/COLIN-LIGHTNING/p/8480054.html
Copyright © 2011-2022 走看看