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; }