jzoj 1220 Pla

Description

 在某条街上有着这么一行比较奇怪的建筑物:每栋建筑物都是一个矩形,而且他们是一个挨着一个的。每栋建筑物都有它的宽度和高度。Task:现在从左到右给出N 栋建筑物的信息。其中每栋建筑物的信息包括它的宽度和高度。然后现在交给你一个刷墙任务:你每一次刷墙的形状都必须是一个矩形。问你最少需要多少次才能把所有建筑物都刷完?

Input

输入文件的第一行有一个整数N(1≤N≤10^6)。
接下来有N 行,每行有两个整数Wi 和Hi(1≤Wi,Hi≤2^31-1,分别表示每栋建筑物的宽度和高度。

Output

输出文件仅包含一个整数,表示你最少需要多少次才能完成这次刷墙任务。

Sample Input

5
1 2
1 3
2 2
2 5
1 4

Sample Output

4

Hint

对于40%的数据,1≤N≤5000
对于80%的数据,1≤N≤250000
对于100%的数据1≤N≤10^6

解题思路

因为只问需要的次数,宽度是没用的,因为要涂满全部建筑物,所以每次都用第一个建筑物的高度往后涂,直到有一的建筑物比他低,但是,比他高的部分是涂不到的,要再花费次数涂,直到涂不了。
所以可以用单调栈解决,先压入第一个建筑物的高度,然后往后扫,当遇到比栈顶高的建筑时,ans+1,把这个高度压入栈中,当遇到比栈顶小的,弹出栈顶至栈顶小于等于这栋建筑的高度,如果栈顶小于这栋建筑的高度,那么ans+1,把这栋压入栈。

Source Code

#include
#include
#include
#include
#include
using namespace std;

const int N=1000001;
int a[N],now[N];

int main()
{
    int n,x,i;
    scanf("%d",&n);
    for (i=1;i<=n;i++)
      scanf("%d%d",&x,&a[i]);
    int ans=1,tail=1;
    now[0]=0; now[1]=a[1];
    for (i=2;i<=n;i++)
    {
        if (a[i]>now[tail]) {ans++; tail++; now[tail]=a[i];}
        if (a[i]<=now[tail]) 
        {
            while (a[i]if (a[i]>now[tail]) {ans++; tail++;now[tail]=a[i];}
        }
    }
    printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(单调栈)