码迷,mamicode.com
首页 > 其他好文 > 详细

单调栈(SOJ 3085)

时间:2019-03-14 13:42:46      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:tput   integer   question   open   acm   ber   core   and   The   

SOJ 3085: windy‘s cake V http://acm.scu.edu.cn/soj/problem.action?id=3085

Problem: Given a list of $n$ positive integers $num[1], ..., num[n]$, denote the score of one sublist from $i$ to $j$ as $(\min_{i\le k\le j}num[k])*\left(\Sigma_{k=i}^{j}num[k]\right)$. The question is that which sublist has the largest score? Output the largest score.

Analysis: we can enumerate each $num[i], 1\le i\le n$ to be the minimum number in one sublist. Therefore, for each $num[i], 1\le i\le n$, we need to find the corresponding sublist, that is, to find the first number $num[i‘]$ that is smaller than $num[i]$ from $i-1$ to $1$ and the first number $num[i‘‘]$ that is smaller than $num[i]$ from $i+1$ to $n$ (similar to SOJ 2511, please see here). Then, for $num[i]$ the score $score[i]=num[i]*\left(\Sigma_{k=i‘}^{i‘‘}num[k]\right)$, and the solution is $\max_{1\le k\le n}score[i]$.

Technique: Maintaining an increasing stack.

Code:

技术图片
#include<iostream>
#include<stack>
using namespace std;
struct node
{
    int no;
    int num;
    int prevNo;
    node(){prevNo=0;}
};
node arr[100005];
stack<node>s;
long long sum[100005];
int main()
{
    int n;
    int temp1;
    int i;
    long long temp2;
    long long ans;
    while(scanf("%d",&n)==1)
    {
        sum[0]=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&temp1);
            sum[i]=sum[i-1]+temp1;
            arr[i].no=i;
            arr[i].num=temp1;
        }
        arr[0].no=0;
        arr[0].num=-1;
        arr[n+1].no=n+1;
        arr[n+1].num=-1;
        s.push(arr[0]);
        ans=0;
        for(i=1;i<=n+1;i++)
        {
            while(arr[i].num<s.top().num)
            {
                temp2=s.top().num*(sum[i-1]-sum[s.top().prevNo]);
                ans=temp2>ans ? temp2 : ans;
                s.pop();
            }
            arr[i].prevNo=s.top().no;
            s.push(arr[i]);
        }
        while(!s.empty())
            s.pop();
        printf("%lld\n",ans);
    }
    return 0;
}
View Code

 

单调栈(SOJ 3085)

标签:tput   integer   question   open   acm   ber   core   and   The   

原文地址:https://www.cnblogs.com/ClearMoonlight/p/10529584.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!