SCU-2511: Moooo【单调栈】

2511: Moooo

Submit your solution     Discuss this problem     Best solutions

Description

Farmer John's N (1 <= N <= 50,000) cows are standing in a very straight row and mooing. Each cow has a unique height h in the range 1..2,000,000,000 nanometers (FJ really is a stickler for precision). Each cow moos at some volume v in the range 1..10,000. This "moo" travels across the row of cows in both directions (except for the end cows, obviously). Curiously, it is heard only by the closest cow in each direction whose height is strictly larger than that of the mooing cow (so each moo will be heard by 0, 1 or 2 other cows, depending on not whether or taller cows exist to the mooing cow's right or left).

The total moo volume heard by given cow is the sum of all the moo volumes v for all cows whose mooing reaches the cow. Since some (presumably taller) cows might be subjected to a very large moo volume, FJ wants to buy earmuffs for the cow whose hearing is most threatened. Please compute the loudest moo volume heard by any cow.

Input

The input file contains multiple test cases, for each test case:

* Line 1: A single integer, N.

* Lines 2..N+1: Line i+1 contains two space-separated integers, h and v, for the cow standing at location i.

Process till EOF.

Output

For each test case, output:
* Line 1: The loudest moo volume heard by any single cow.

Sample Input

3
4 2
3 5
6 10

Sample Output

7

Source

USACO 2006 March

解题思路:

有一排牛,我们输入牛的身高和叫声,要求是牛的叫声是会被左右两边比他身高高的第一头牛听到,问那一头牛听到的叫声最大,所以我们从左右两边各进行一次,利用栈将比当前这头牛低的全部出栈,找到比他高的带当前位置累加起来。

 

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
#define LL long long 
#define M 100009
using namespace std;
int h[M],v[M],n,ans[M];
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		 memset(ans,0,sizeof(ans));
		 int i,j;
		 stack<int> s;
		 for(i=0;i<n;i++)
		 {
		 	scanf("%d%d",&h[i],&v[i]);
		 }
		 int you=0;
		 for(i=0;i<n;i++)
		 {
		 	while(!s.empty()&&h[s.top()]<h[i]) s.pop();
		 	if(!s.empty())
		 	{
		 		ans[s.top()]+=v[i];
		 		you=max(you,ans[s.top()]);
		 	}
		 	s.push(i);
		 }
		 while(!s.empty())
		 s.pop();
		 for(i=n-1;i>=0;i--)
		{
			while(!s.empty()&&h[s.top()]<h[i]) s.pop();
			if(!s.empty())
			{
				ans[s.top()]+=v[i];
				you=max(you,ans[s.top()]);
			}
			s.push(i);
		}
		printf("%d\n",you);
	}
	return 0;
} 
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值