noip模拟赛 财富

题目描述
LYK有n个小伙伴。每个小伙伴有一个身高hi。
这个游戏是这样的,LYK生活的环境是以身高为美的环境,因此在这里的每个人都羡慕比自己身高高的人,而每个人都有一个属性ai表示它对身高的羡慕值。
这n个小伙伴站成一列,我们用hi来表示它的身高,用ai来表示它的财富。
每个人向它的两边望去,在左边找到一个最近的比自己高的人,然后将ai朵玫瑰给那个人,在右边也找到一个最近的比自己高的人,再将ai朵玫瑰给那个人。当然如果没有比自己身高高的人就不需要赠送别人玫瑰了。也就是说一个人会给0,1,2个人玫瑰(这取决于两边是否有比自己高的人)。
每个人都会得到若干朵玫瑰(可能是0朵),LYK想知道得了最多的玫瑰的那个人得了多少玫瑰。(然后嫁给他>3<)

输入格式(treasure.in)
第一行一个数n表示有n个人。
接下来n行,每行两个数hi,ai。

输出格式(treasure.out)
一个数表示答案。

输入样例
3
4 7
3 5
6 10

输出样例
12

样例解释
第一个人会收到5朵玫瑰,第二个没人送他玫瑰,第三个人会收到12朵玫瑰。

数据范围
对于50%的数据n<=1000,hi<=1000000000。
对于另外20%的数据n<=50000,hi<=10。
对于100%的数据1<=n<=50000,1<=hi<=1000000000。1<=ai<=10000。

分析:单调栈裸题,先顺着扫一遍,维护一个单调下降的单调栈,每次出栈的时候统计答案,然后反过来扫一遍就过了.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int n, a[50010], h[50010], ans[50010], cur, flag[50010], q[50010], anss;

int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d%d", &h[i], &a[i]);
    cur = 1;
    q[1] = h[1];
    flag[1] = 1;
    for (int i = 2; i <= n; i++)
    {
        while (cur && h[i] > q[cur])
        {
            ans[i] += a[flag[cur]];
            cur--;
        }
        ++cur;
        flag[cur] = i;
        q[cur] = h[i];
    }
    memset(q, 0, sizeof(q));
    cur = 1;
    q[1] = h[n];
    flag[1] = n;
    for (int i = n - 1; i; i--)
    {
        while (cur && h[i] > q[cur])
        {
            ans[i] += a[flag[cur]];
            cur--;
        }
        cur++;
        flag[cur] = i;
        q[cur] = h[i];
    }
    for (int i = 1; i <= n; i++)
        anss = max(anss, ans[i]);
    printf("%d\n", anss);

    return 0;
}

 

posted @ 2017-10-18 13:53  zbtrs  阅读(112)  评论(0编辑  收藏  举报