单调栈(SOJ 2511)

SOJ 2511: Moooo http://acm.scu.edu.cn/soj/problem.action?id=2511

问题:给出$n$个元素$node[i], 0\le i<n$,每个元素$node[i]$有两个属性heightvolume.对于每个$node[i]$,它的volume只能被两边height值比它的大并且离它最近的元素取得。求解可以取得最大volume的元素并输出最大的volume.

分析:对每个元素$node[i]$,我们只需找出从$i-1$到$0$(从$i+1$到$n-1$)中第一个height大于$node[i]$的height的元素$node[i']$($node[i'']$),这一点跟SOJ 3085类似(参考这里).

方法:维护一个单调递减栈。

代码:

#include<iostream>
#include<stack>
#include<cstring>
using namespace std;
struct node
{
    int no;
    int hgt;
    int vol;
};
node cows[50005];
int volume[50005];
int main()
{
    int N;
    int i;
    stack<node>s;
    int ans;
    while(scanf("%d",&N)==1)
    {
        for(i=0;i<N;i++)
        {
            scanf("%d%d",&cows[i].hgt,&cows[i].vol);
            cows[i].no=i;
        }
        memset(volume,0,sizeof(volume));
        for(i=0;i<N;i++)
        {    
            while(!s.empty() && cows[i].hgt>s.top().hgt)
            {
                volume[i]+=s.top().vol;
                s.pop();    
            }
            if(!s.empty())
                volume[s.top().no]+=cows[i].vol;
            s.push(cows[i]);
        }
        while(!s.empty())
            s.pop();
        ans=0;
        for(i=0;i<N;i++)
            ans=volume[i]>ans ? volume[i] : ans;
        printf("%d\n",ans);
    }
    return 0;
}
View Code

posted on 2019-03-14 07:28  小叶子曰  阅读(252)  评论(0编辑  收藏  举报

导航