poj 2796 Feel Good

来源:互联网 发布:avision扫描仪软件 编辑:程序博客网 时间:2024/05/21 14:41

应该是用单调栈解决

用l[i] r[i] 存i点向左和向右比i点的值大的最多能到哪个位置

也就是 i 点所求的区间就是 l[i] 到 r[i]

再枚举每个点 求出符合题意的最优解


#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <cmath>#include <algorithm>#include <vector>#include <queue>#include <map>#define inf 0x3f3f3f3fusing namespace std;int n,i,l[100010],r[100010],ansr,ansl;__int64 ans,tmp,ty[100010],sum[100010];int main(){    while(~scanf("%d",&n))    {        sum[0]=0;        for(i=1;i<=n;i++)        {            scanf("%I64d",&ty[i]);            sum[i]=sum[i-1]+ty[i];            l[i]=i;            r[i]=i;        }        for(i=2;i<=n;i++)        {            while(l[i]>1&&ty[l[i]-1]>=ty[i])                l[i]=l[l[i]-1];        }        for(i=n-1;i>0;i--)        {            while(r[i]<n&&ty[r[i]+1]>=ty[i])                r[i]=r[r[i]+1];        }        ans=-1;        for(i=1;i<=n;i++)        {            tmp=ty[i]*(sum[r[i]]-sum[l[i]-1]);            if(tmp>ans){                ansr=r[i];                ansl=l[i];                ans=tmp;            }        }        printf("%I64d\n%d %d\n",ans,ansl,ansr);    }    return 0;}


0 0
原创粉丝点击