Moooo SCU - 2511

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



题解:单调栈,可以分成两步来求。

1.假设声音只能从左到右传播,可以顺着从左到右建一个单调递减栈,当high[i]大于栈顶时,弹出栈顶, sum[i]加上栈顶的声音值。

2.假设声音只能从右到左传播,可以顺着从右到左建一个单调递减栈,剩余步骤同1.

    最后把1,2两个sum的贡献值一次加起来,取最大。



#include"stdio.h"
#include"string.h"
#include"algorithm"
#include"cstdio"
using namespace std;
const int max_n=5*(1e4)+10;
int high[max_n],voice[max_n];
int stack[max_n],inde[max_n];
int sum[max_n];
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		int i;
		for(i=0;i<n;i++)
		scanf("%d%d",&high[i],&voice[i]); 
		memset(stack,0,sizeof(stack));
		memset(inde,0,sizeof(inde));
		memset(sum,0,sizeof(sum)); 
		int top=0;
		stack[top]=high[0];inde[top++]=0;
		for(i=1;i<n;i++)
		{
			if(high[i]>stack[top-1])
			{
				while(top>0&&high[i]>stack[top-1])
				{
					sum[i]+=voice[inde[top-1]];
					top--;
				}
				stack[top]=high[i];
				inde[top++]=i;
			}
			else
			{
				stack[top]=high[i];
				inde[top++]=i;
			}
		}
		memset(stack,0,sizeof(stack));
		memset(inde,0,sizeof(inde));
		top=0;
		stack[top++]=high[n-1];inde[0]=n-1;
		for(i=n-2;i>=0;i--)
		{
			if(high[i]>stack[top-1])
			{
				while(top>0&&high[i]>stack[top-1])
				{
					sum[i]+=voice[inde[top-1]];
					top--;
				}	
				stack[top]=high[i];
				inde[top++]=i;
			}
			else
			{
				stack[top]=high[i];
				inde[top++]=i;
			}
		}
		int ret=0;
		for(i=0;i<n;i++)
		ret=max(ret,sum[i]);
		printf("%d\n",ret);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值