题意:给定一个序列,需要找出某个子序列S使得Min(a[i])*Σa[i] (i属于S序列)最大

正解:单调栈

这题的暴力还是很好想的,只需3分钟的事就可以码完,以每个点拓展即可,但这样的复杂度是O(n^2)的,肯定会TLE

以暴力的思想作为基础,再进行深层次思考,考虑每个点往周围拓展的时候,都要走到最远的地方停下来,也就是说会有一个左上限,一个右上限(命名为:pre、next),不难发现再枚举5、4、3、2、1这个序列的时候,每次都要往左扫描到最左边,显然这是做了重复的事情,于是机智的我马上想到了单调栈。为什么说具有单调性呢,因为x<y,对于x可以控制的所有范围显然y都可以控制,这不是废话吗。于是我们想到了用单调栈来解决这个问题。

什么是单调栈呢,单调栈分为单调增栈和单调减栈两种。比如说:单调增栈就是以某一个值为最小值,然后维护一个单调递增的序列。将一元素加入栈时,先判断它是否大于栈顶元素,若是大于栈顶元素,加入栈。否则,将栈顶元素出栈,直到栈顶元素小于要加入栈的元素。

对于这道题而言,我们不妨维护每个端点能够往前往后拓展的最大值,在删除栈顶元素的时候“继承”此时栈顶的范围就可以了(上面提到的单调性)

呼,这样的话这道单调栈裸题就可以AC了。记得开long long。第一次提交又没开long long然后WA了

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<stack>
using namespace std;
typedef long long LL;
const int MAXN = ;
int n;
LL a[MAXN];
LL ans,now;
LL qian[MAXN];
int nowl,nowr; struct node{
int jilu;
int pre,next;
LL num;
}; stack<node>Stack; inline LL getlong(){
char c=getchar();LL w=;int q=;
while( (c<'' || c>'') && c!='-' ) c=getchar();
if(c=='-') c=getchar(),q=;
while(c<='' && c>='') w=w*+c-'',c=getchar();
return q?-w:w;
} inline void Init(){
scanf("%d",&n);
ans=now=-; nowl=nowr=; qian[]=;
for(int i=;i<=n;i++) a[i]=getlong(),qian[i]=qian[i-]+a[i];
while(!Stack.empty()) Stack.pop();
} inline void work(){
node jump; jump.num=a[];
jump.pre=jump.next=;
jump.jilu=;
Stack.push(jump); node ljh;
for(int i=;i<=n;i++) {
ljh.num=a[i];
ljh.pre=ljh.next=;
ljh.jilu=i; while(!Stack.empty() && a[i]<=Stack.top().num) {
jump=Stack.top();
Stack.pop();
if(!Stack.empty()) Stack.top().next+=jump.next;
ljh.pre+=jump.pre; now=jump.num*(qian[ jump.jilu+jump.next- ]-qian[ jump.jilu-jump.pre ]); if(now>ans) {
ans=now;
nowl=jump.jilu-jump.pre+; nowr=jump.jilu+jump.next-;
}
} Stack.push(ljh);
} while(!Stack.empty()) {
jump=Stack.top();
Stack.pop(); if(!Stack.empty()) Stack.top().next+=jump.next; now=jump.num*(qian[ jump.jilu+jump.next- ]-qian[ jump.jilu-jump.pre ]);
if(now>ans) {
ans=now;
nowl=jump.jilu-jump.pre+; nowr=jump.jilu+jump.next-;
}
} if(n==) ans=;
printf("%lld\n%d %d\n",ans,nowl,nowr);
} int main()
{
freopen("poj2796.in","r",stdin);
freopen("poj2796.out","w",stdout); Init(); work();
return ;
}

POJ2796 Feel Good 单调栈的更多相关文章

  1. upc组队赛1 小C的数学问题【单调栈】(POJ2796)

    小C的数学问题 题目描述 小C是个云南中医学院的大一新生,在某个星期二,他的高数老师扔给了他一个问题. 让他在1天的时间内给出答案. 但是小C不会这问题,现在他来请教你. 请你帮他解决这个问题. 有n ...

  2. poj2796 维护区间栈//单调栈

    http://poj.org/problem?id=2796 题意:给你一段区间,需要你求出(在这段区间之类的最小值*这段区间所有元素之和)的最大值...... 例如: 6 3 1 6 4 5 2 以 ...

  3. POJ2796(单调栈)

    Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12987   Accepted: 3639 Case T ...

  4. 【POJ2796】Feel Good 单调栈

    题目大意:给定一个长度为 N 的序列,求任意区间 [ l , r ] 中最小的\(min\{v[i],i\in[l,r] \}*\Sigma_{i=l}^rv[i]\). 题解:这是一道具有标准单调栈 ...

  5. 单调栈poj2796

    题意:给你一段区间,需要你求出(在这段区间之类的最小值*这段区间所有元素之和)的最大值...... 例如: 6 3 1 6 4 5 2 以4为最小值,向左右延伸,6 4 5  值为60....... ...

  6. POJ2796 Feel Good(单调栈)

    题意:给一个非负整数序列,求哪一段区间的权值最大,区间的权值=区间所有数的和×区间最小的数. 用单调非递减栈在O(n)计算出序列每个数作为最小值能向左和向右延伸到的位置,然后O(n)枚举每个数利用前缀 ...

  7. UVA 1619/POJ2796 滑窗算法/维护一个单调栈

    Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12409   Accepted: 3484 Case T ...

  8. POJ2796【单调栈】

    题意: 题意:n个数,求某段区间的最小值*该段区间所有元素之和的最大值 思路: 主要参考:http://www.cnblogs.com/ziyi–caolu/archive/2013/06/23/31 ...

  9. POJ2796Feel Good[单调栈]

    Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13376   Accepted: 3719 Case T ...

随机推荐

  1. vs2015企业版太大了

    安装教程 http://www.cnblogs.com/mephisto/archive/2015/07/22/4666032.html#!comments 新功能 http://news.cnblo ...

  2. [py]特殊函数+文件保护

    1函数的好处 2函数的全局变量和局部变量 3,包和文件夹的区别 4,__name__ __file__ __doc__ #判断是否为主程序 if __name__=='__main__': pass ...

  3. 向jboss写入服务器日志

    实际开发中,记录日志是常用的功能,jboss默认情况下已经记录了很多运行日志,如果开发人员要手动在server.log中写入日志,可以参考下面的方法: package utils; import ja ...

  4. 解决Kafka-1194问题

    生产环境中使用Kafka作为日志处理的中间件,系统结构是这样的.自12月上线一个多月来,系统运行稳定. 用过kafka的都知道,Kafka产生的消息全部存储到硬盘文件中,并且在消息被消费后不会被立即删 ...

  5. PRML读书会第八章 Graphical Models(贝叶斯网络,马尔科夫随机场)

    主讲人 网神 (新浪微博: @豆角茄子麻酱凉面) 网神(66707180) 18:52:10 今天的内容主要是: 1.贝叶斯网络和马尔科夫随机场的概念,联合概率分解,条件独立表示:2.图的概率推断in ...

  6. 求解最大正方形面积 — leetcode 221. Maximal Square

    本来也想像园友一样,写一篇总结告别 2015,或者说告别即将过去的羊年,但是过去一年发生的事情,实在是出乎平常人的想象,也不具有代表性,于是计划在今年 6 月份写一篇 "半年总结" ...

  7. mvc5+ef6+Bootstrap 项目心得--WebGrid

    1.mvc5+ef6+Bootstrap 项目心得--创立之初 2.mvc5+ef6+Bootstrap 项目心得--身份验证和权限管理 3.mvc5+ef6+Bootstrap 项目心得--WebG ...

  8. Linux进程间通信之共享内存

    一,共享内存  内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内存,被多个进程同时映射的物理内存,即共享内存.  映射物理内存叫挂接,用完以后解除映射叫脱接. 1,共享内存的特点 ...

  9. js队列

    用指针和数组模拟基本队列 http://blog.csdn.net/zhuwq585/article/details/53177192 js下的事件队列,或者异步队列 http://www.jb51. ...

  10. word2vec使用说明(google工具包)

    word2vec使用说明   转自:http://jacoxu.com/?p=1084. Google的word2vec官网:https://code.google.com/p/word2vec/ 下 ...