题目描述
Farmer John的N(1<=N<=50,000)头奶牛整齐地站成一列“嚎叫”。每头奶牛有一个确定的高度h(1<=h<=2000000000),叫的音量为v (1<=v<=10000)。每头奶牛的叫声向两端传播,但在每个方向都只会被身高严格大于它的最近的一头奶牛听到,所以每个叫声都只会 被0,1,2头奶牛听到(这取决于它的两边有没有比它高的奶牛)。 一头奶牛听到的总音量为它听到的所有音量之和。自从一些奶牛遭受巨大的音量之后,Farmer John打算买一个耳罩给被残害得最厉 害的奶牛,请你帮他计算最大的总音量。
输入格式
第1行:一个正整数N.
第2到N+1行:每行包括2个用空格隔开的整数,分别代表站在队伍中第i个位置的奶牛的身高以及她唱歌时的音量.
输出格式
队伍中的奶牛所能听到的最高的总音量.
我们可以用单调栈来维护一个单调下降的序列,这样的话当比当前奶牛高的第一头奶牛入栈时,当前奶牛就会出栈并且更新比它高的第一头奶牛所听到的声音值。
由于声音会两边传播,我们正着跑一遍再反着跑一遍即可。时间复杂度为O(N).
#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 50001
using namespace std;
inline long long read(){
register long long x(0); register char c(getchar());
while(c<'0'||'9'<c) c=getchar();
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x;
}
long long stack[maxn],top;
long long h[maxn],ans[maxn];
long long v[maxn],n;
int main(){
n=read();
for(register long long i=1;i<=n;i++) h[i]=read(),v[i]=read();
for(register long long i=1;i<=n;i++){
while(top&&h[stack[top]]<h[i]) ans[i]+=v[stack[top--]];
stack[++top]=i;
}
top=0;
for(register long long i=n;i>=1;i--){
while(top&&h[stack[top]]<h[i]) ans[i]+=v[stack[top--]];
stack[++top]=i;
}
long long mmax=0;
for(register long long i=1;i<=n;i++) mmax=max(mmax,ans[i]);
printf("%lld
",mmax);
return 0;
}
*不开long long见祖宗