51nod 1279 扔盘子(单调栈)

版权声明:如果发现错误或者其他什么不足之处。请留言。 https://blog.csdn.net/gyhguoge01234/article/details/73420106

开始是直接从井口往里扔,复杂度是O(n^2),超时。。然后呢,你会发现,如果井上边的宽度小,下边的宽度大,那么下边宽度多大都是没用的,所以就让他等于上边宽度就好了。然后处理后这个井的宽度从上到下就是一个非递增的了,然后从下向上匹配,O(n)。。。。还可以用单调栈预处理

#include <cstdio>
#include <cstring>
const int MAXN = 50050;
int n,m,num;
int jing[MAXN];
int panzi[MAXN];
int main()
{
    scanf("%d %d",&n,&m);
    scanf("%d",&jing[0]);
    for(int i = 1; i < n; ++i)
    {
        scanf("%d",&jing[i]);
        if(jing[i] > jing[i-1])
            jing[i] = jing[i-1];
    }
    for(int i = 0; i < m; ++i)
        scanf("%d",&panzi[i]);
    if(panzi[0] > jing[0])
    {
        printf("0\n");
        return 0;
    }
    int index = n;
    int cnt = 0;
    for(int i = 0; i < m; ++i)
    {
        for(int j = index-1; j >= 0; --j)
        {
            if(jing[j] >= panzi[i])
            {
                index = j;
                ++cnt;
                break;
            }
        }
    }
    printf("%d\n",cnt);
    return 0;
}

单调栈:

#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;

int n,m,w;
int minn = 1e9+10;

int main()
{
    stack<int> s;
    cin >> n >> m;
    for(int i = 0; i < n; ++i)
    {
        cin >> w;
        if(w < minn)
            minn = w;
        s.push(minn);
    }
    int res = 0;
    for(int i = 0; i < m; ++i)
    {
        cin >> w;
        while(s.size())
        {
            if(w > s.top())
                s.pop();
            else
            {
                ++res;
                s.pop();
                break;
            }
        }
    }
    cout << res <<endl;
    return 0;
}
阅读更多

没有更多推荐了,返回首页