zoukankan      html  css  js  c++  java
  • poj 2796 Feel Good(单调栈)

    题目链接:poj 2796 Feel Good

    题意:

    给你n个数,定义一个区间的值为这个区间的最小值乘上这个区间的数的和。

    让你选一个值最大的区间。

    题解:

    考虑以每一个数作为区间的最小值,那么现在问题就转换成了如果以这个数为最小值,那么从这个位置开始左右最远能到哪个位置。

    这里就要用到单调栈了。维护一个单调递减的栈,栈顶就是当前的最小值。

    然后从左往右扫一遍,从右往左扫一遍就行了。

    如果不懂原理的话,网上搜搜这题的其他题解,比我讲的详细。(懒)

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
     4 using namespace std;
     5 typedef long long ll;
     6 
     7 const int N=1e5+7;
     8 int n,a[N],l[N],r[N],S[N],top;
     9 ll sum[N];
    10 int main()
    11 {
    12     while(~scanf("%d",&n))
    13     {
    14         F(i,1,n)scanf("%d",a+i),sum[i]=sum[i-1]+a[i];
    15         top=0;
    16         F(i,1,n)
    17         {
    18             l[i]=i;
    19             while(top&&a[i]<=a[S[top]])l[i]=l[S[top]],top--;
    20             S[++top]=i;
    21         }
    22         top=0;
    23         for(int i=n;i>=1;i--)
    24         {
    25             r[i]=i;
    26             while(top&&a[i]<=a[S[top]])r[i]=r[S[top]],top--;
    27             S[++top]=i;
    28         }
    29         ll ans=-1;int L,R;
    30         F(i,1,n)
    31         {
    32             ll tmp=(sum[r[i]]-sum[l[i]-1])*a[i];
    33             if(tmp>ans)ans=tmp,L=l[i],R=r[i];
    34         }
    35         printf("%lld
    %d %d
    ",ans,L,R);
    36     }
    37     return 0;
    38 }
    View Code
  • 相关阅读:
    unigui+fastreport报表打印
    MySQL索引类型总结和使用技巧以及注意事项
    Vue.js 和 MVVM
    Go -- 中结构体与字节数组能相互转化
    iOS算法合集
    postman中 form-data、x-www-form-urlencoded、raw、binary的区别
    JS注入
    JS页面间传值
    上手ReactiveCocoa之基础篇
    数据结构与算法题整理
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7131573.html
Copyright © 2011-2022 走看看