题目,给定一个数列,n <= 1e5 。要求找出一个区间,使得其内区间最小值 * 区间总和的值最大,要求输出区间。

首先先维护一个单调递增的栈,同时记录一个lef值表示:lef[i]表示当前栈内这个元素能匹配的最左值,什么意思呢?就是在最左边那里,它是最小的。a[lef[i] - 1] < a[lef[i]] 的。这样的话,每次弹出一个元素,我就能知道它在那个区间内最小的,左区间是lef[i],右区间栈顶元素的位置。这样是最优的,因为你匹配多一些大的数字更好。

用simple来说

3 1 6 4 5 2

开始的时候,是3入栈,记录lef[1] = 1。我简陋写为 3 (1,1)

然后是1了,比3小,所以3出栈,3出栈后注意了,要计算,最左区间,自然是1,最右区间,就是当前栈顶元素的位置,也是1。tans = 9;  然后要跟新1的最左值,是1。

6进来,直接进。1 (1,2) , 6 (3, 3)

然后4进来,弹出6,计算6.栈内是 1 (1,2)  4(3, 4)

5进来。栈内是 1 (1,2)  4(3, 4)5(5,5)

2进来。把5弹出,计算5.

把4弹出,注意了。区间是4的最左值,最右值是栈顶元素的位置,当前栈顶元素是5,位置是5.所以表明4在{6,4,5}最小。计算。

主要是弹出一个元素,就要对那个元素进行 计算。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = + ;
int a[maxn];
int stack[maxn]; //只保存位置即可,大小关系可以调用a[stack[top]] 判断
int lef[maxn]; //传入栈的位置,就可以得到对应元素在最左区间内最小
LL sum[maxn];
void work ()
{
int n;
scanf ("%d", &n);
for (int i = ; i <= n; ++i) {
scanf ("%d", &a[i]);
sum[i] = sum[i - ] + a[i];
}
a[n + ] = -; //防止全部都是递增
LL ans = -, L, R;
int top = ;
for (int i = ; i <= n + ; ++i) {
int TT = stack[top]; // 栈内元素到栈顶元素,这个区间最小值
int toleft = i; //保存插入后上一个元素的最左值
while (top >= && a[i] < a[stack[top]]) { //等于的话,不如让它扩大
LL t = (sum[TT] - sum[lef[stack[top]] - ]) * a[stack[top]];
if (t > ans) {
ans = t; L = lef[stack[top]]; R = TT;
}
toleft = lef[stack[top]];
--top;
// printf ("%d\n", top);
// printf ("%lld****\n", ans);
}
++top;
stack[top] = i;
lef[stack[top]] = toleft;
//printf ("%d %d %d\n", top, lef[stack[top]], stack[top]);
}
printf ("%lld\n", ans);
printf ("%lld %lld\n", L, R);;
return ;
}
int main ()
{
#ifdef local
freopen("data.txt","r",stdin);
#endif
work ();
return ;
}

POJ 2796:Feel Good 单调栈的更多相关文章

  1. poj 2796 Feel Good单调栈

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

  2. poj 2796 Feel Good 单调栈区间问题

    Feel Good 题意:给你一个非负整数数组,定义某个区间的参考值为:区间所有元素的和*区间最小元素.求该数组中的最大参考值以及对应的区间. 比如说有6个数3 1 6 4 5 2 最大参考值为6,4 ...

  3. POJ 3658 Artificial Lake (单调栈)

    题意: 析:利用单调栈,维护一个单调递增的栈,首先在最低的平台开始,每次向两边进行扩展,寻找两边最低的,然后不断更新宽度. 代码如下: #pragma comment(linker, "/S ...

  4. poj 2559 Largest Rectangle(单调栈)

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 26549 ...

  5. POJ - 2796 Feel Good 单调递增栈+前缀和

    Feel Good Bill is developing a new mathematical theory for human emotions. His recent investigations ...

  6. POJ 3415 后缀数组+单调栈

    题目大意: 给定A,B两种字符串,问他们当中的长度大于k的公共子串的个数有多少个 这道题目本身理解不难,将两个字符串合并后求出它的后缀数组 然后利用后缀数组求解答案 这里一开始看题解说要用栈的思想,觉 ...

  7. poj 2796 Feel Good 单调队列

    Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 8753   Accepted: 2367 Case Ti ...

  8. [poj 2796]单调栈

    题目链接:http://poj.org/problem?id=2796 单调栈可以O(n)得到以每个位置为最小值,向左右最多扩展到哪里. #include<cstdio> #include ...

  9. POJ 2796:Feel Good(单调栈)

    http://poj.org/problem?id=2796 题意:给出n个数,问一个区间里面最小的元素*这个区间元素的和的最大值是多少. 思路:只想到了O(n^2)的做法. 参考了http://ww ...

  10. POJ 2796 Feel Good 【单调栈】

    传送门:http://poj.org/problem?id=2796 题意:给你一串数字,需要你求出(某个子区间乘以这段区间中的最小值)所得到的最大值 例子: 6 3 1 6 4 5 2 当L=3,R ...

随机推荐

  1. Linux CentOS安装Azure Cli工具

    vim /etc/yum.repos.d/epel.repo [epel] name=epel baseurl=http://mirrors.sohu.com/fedora-epel/6/$basea ...

  2. 【转】Pro Android学习笔记(五三):调试和分析(1):Debug视图和DDMS视图

    目录(?)[-] Debug视图 DDMS视图 查看应用运行状态 进入debug状态 HPROF Thread信息 Method信息 Stop 截图 UI层次架构信息 其它的 Tab中提供的功能 我们 ...

  3. shell入门-shell特性

    1.关于! 命令:!! 说明: 执行上一条命令 [root@wangshaojun ~]# pwd/root[root@wangshaojun ~]# !!pwd/root 命令:!n (n表示数字) ...

  4. C语言32关键字

    关键字 说明 auto 声明自动变量 short 声明短整型变量或函数 int 声明整型变量或函数 long 声明长整型变量或函数 float 声明浮点型变量或函数 double 声明双精度变量或函数 ...

  5. 【问题】Expandable数据集的定义的正确方法,TabActivity弃用替代,Gallery替代,imageswitcher

    Expandable 问题: http://www.cnblogs.com/xingyyy/p/3389611.html 扩展阅读:http://blog.csdn.net/lmj623565791/ ...

  6. sql 删除重复数据保留一条

    --创建测试表 CREATE TABLE TEST ( DEPTNO ), DNAME ), LOC ) ); --插入测试数据 , 'test1', 'test2'); , 'test1', 'te ...

  7. hdu1058

    #include<iostream> #include<string> using namespace std; int const N = 4; int map[N] = { ...

  8. XLua 基础

    一.Lua文件加载 1.Resources文件夹下加载  xxx.lua.txt  文件 1.)Resources加载xuaTest文件 // 1.Resources加载xuaTest文件 TextA ...

  9. Java之Spring Boot详解(非原创)

    文章大纲 一.Spring Boot 概述二.Spring Boot 入门案例三.Spring Boot核心功能代码实战四.项目源码与资料下载五.参考文章   一.Spring Boot 概述 1. ...

  10. Element-ui Cascader 级联选择器 同时返回 value 和 label

    给 cascader 组件赋值一个别名 ref="cascaderAddr" <el-form-item label="部门" prop="or ...