题目,给定一个数列,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. poj 1519 Digital Roots (计算根数字)

    一.Description The digital root of a positive integer is found by summing the digits of the integer. ...

  2. HDOJ1059(多重背包)

    1.解法一:多重背包 #include<iostream> #include<cstdio> using namespace std; #define MAX(a,b) (a& ...

  3. windows 创建和调用 动态库,静态库

    windows创建和调用静态库 // MathFuncsLib.h namespace MathFuncs { class MyMathFuncs { public: // Returns a + b ...

  4. 3.JasperReports学习笔记3-在浏览器生成PDF文件

    转自:https://i.cnblogs.com/posts?categoryid=921197 一.新建web工程,导入jasperreports所需的jar包,配置web.xml <serv ...

  5. ctime、atime、mtime时间

    区分一个文件或者目录的更改时间(change time,ctime),访问时间(access time,atime)以及修改时间(modify time,mtime)很重要. ctime——在Unix ...

  6. 07_ddms透视图介绍

    通过ADB(Android Debug Bridge)安卓调试桥把你的Eclipse(集成开发环境)和你的设备连接在一起.有时候ADB可能会被其他的东西占用.例如WPS会跟你抢ADB(抢端口).如果你 ...

  7. [51nod1212]最小生成树模板

    解题关键:注意下标 解法一:prim算法 #include<bits/stdc++.h> #define maxv 1002 #define maxm 50002 #define INF ...

  8. UGUI解决嵌套使用多个ScrollRect时的Drag拖动冲突问题

    很简单,直接看代码: using UnityEngine.UI; using UnityEngine.EventSystems; using UnityEngine; /// <summary& ...

  9. 22. CTF综合靶机渗透(十五)

    靶机说明: Game of Thrones Hacking CTF This is a challenge-game to measure your hacking skills. Set in Ga ...

  10. node安装和配置

    windows 环境 安装node node下载地址 下载后点击安装,默认下一步即可(安装路径可更改为d:盘) 检测PATH环境变量是否配置了Node.js 点击开始=>运行=>输入&qu ...