财富(treasure)

Time Limit:1000ms   Memory Limit:128MB

 

题目描述

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。

 

题解:预处理每个数左右第一个比他大的数 O(n)更新的答案

#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 2100000000
using namespace std;

int n,ret;
int l[50009],r[50009],ans[50009];
struct Per{
    int h,v;
}per[50009];

inline int read(){
    char ch=getchar();int x=0,f=1;
    for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
    return x*f;
}

int main(){
    n=read();
    for(int i=1;i<=n;i++){
        per[i].h=read();per[i].v=read();
        l[i]=r[i]=i;
    }    
    per[n+1].h=per[0].h=inf;
    for(int i=1;i<=n;i++){
        int h=per[i].h;
        while(h>=per[l[i]-1].h)l[i]=l[i]-1;
        while(h>=per[r[i]+1].h)r[i]=r[i]+1;
    }
    for(int i=1;i<=n;i++){
        l[i]--;r[i]++;
        if(l[i]!=0)ans[l[i]]+=per[i].v;
        ret=max(ret,ans[l[i]]);
        if(r[i]<=n)ans[r[i]]+=per[i].v;
        ret=max(ret,ans[r[i]]); 
    } 
    printf("%d\n",ret);
    return 0;
}
/*
9
9 15
9 9
19 15
11 3
2 15
15 10
10 3
15 17
20 1
*/
AC

相关文章: