POJ 2796 Feel Good 【单调栈】
传送门:http://poj.org/problem?id=2796
题意:给你一串数字,需要你求出(某个子区间乘以这段区间中的最小值)所得到的最大值
例子:
6
3 1 6 4 5 2
当L=3,R=5时这段区间总和为6+4+5=15,最小值为4,所以最后的结果为60.
思路:单调栈的板子题了。没学过单调栈的我只能现学了。单调栈分为单调递增栈,单调递减栈。而这个题呢,要用到单调递增栈。怎么维护单调栈呢?那就是在遇到一个元素大于栈顶元素时,就将该元素加入栈中。(假定即为区间最小值,区间左端点L=i,区间右端点R=i)如果遇到一个小于栈顶的元素时,则把栈里面的元素弹出来,同时记录该元素向左延申的最大长度,即更新区间左端点。在弹出栈顶元素时把这个要弹出栈的元素(栈顶元素)的右端点赋值给这个它的下一个元素(当前栈中次大元素),即更新区间右端点,同时更新答案。
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 1e6 + 10;
struct node
{
int l;
int r;
long long num;
} s[maxn];
long long a[maxn];
long long sum[maxn];
long long ans;
int ans_l;
int ans_r;
int top;
int n;
void solve(int top)
{
int l = s[top].l;
int r = s[top].r;
//更新答案
if((sum[r] - sum[l - 1])*s[top].num >= ans)
{
ans = (sum[r] - sum[l - 1]) * s[top].num;
ans_r = r;
ans_l = l;
}
//向右延申
if(top > 0)
{
s[top - 1].r = s[top].r;
}
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%I64d", &a[i]);
//记录前缀和
sum[i] = a[i] + sum[i - 1];
}
top = -1;
for(int i = 1; i <= n; i++)
{
//初始假定a[i]为区间最小值,左区间,右区间都为i
node v;
v.l = i;
v.r = i;
v.num = a[i];
//加入的元素大于栈顶元素向左延申
while(top != -1 && s[top].num >= a[i])
{
solve(top);
//一直向左更新 ,直到某一个元素小于加入的元素
v.l = s[top].l;
top--;
}
s[++top].l = v.l;
s[top].r = v.r;
s[top].num = a[i];
}
//单调栈中元素可能不为空
while(top != -1)
{
solve(top);
top--;
}
cout << ans << endl;
cout << ans_l << " " << ans_r << endl;
}
POJ 2796 Feel Good 【单调栈】的更多相关文章
- poj 2796 Feel Good单调栈
Feel Good Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 20408 Accepted: 5632 Case T ...
- poj 2796 Feel Good 单调栈区间问题
Feel Good 题意:给你一个非负整数数组,定义某个区间的参考值为:区间所有元素的和*区间最小元素.求该数组中的最大参考值以及对应的区间. 比如说有6个数3 1 6 4 5 2 最大参考值为6,4 ...
- POJ 3658 Artificial Lake (单调栈)
题意: 析:利用单调栈,维护一个单调递增的栈,首先在最低的平台开始,每次向两边进行扩展,寻找两边最低的,然后不断更新宽度. 代码如下: #pragma comment(linker, "/S ...
- poj 2559 Largest Rectangle(单调栈)
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26549 ...
- POJ - 2796 Feel Good 单调递增栈+前缀和
Feel Good Bill is developing a new mathematical theory for human emotions. His recent investigations ...
- POJ 3415 后缀数组+单调栈
题目大意: 给定A,B两种字符串,问他们当中的长度大于k的公共子串的个数有多少个 这道题目本身理解不难,将两个字符串合并后求出它的后缀数组 然后利用后缀数组求解答案 这里一开始看题解说要用栈的思想,觉 ...
- poj 2796 Feel Good 单调队列
Feel Good Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 8753 Accepted: 2367 Case Ti ...
- [poj 2796]单调栈
题目链接:http://poj.org/problem?id=2796 单调栈可以O(n)得到以每个位置为最小值,向左右最多扩展到哪里. #include<cstdio> #include ...
- POJ 2796:Feel Good(单调栈)
http://poj.org/problem?id=2796 题意:给出n个数,问一个区间里面最小的元素*这个区间元素的和的最大值是多少. 思路:只想到了O(n^2)的做法. 参考了http://ww ...
随机推荐
- Frequently arduino function
unctions 功能if(Serial) ...
- Day2-T4
原题目 当然这是原题+,要输路径的.所以必须DFS. Describe:DP or DFS code: #include<bits/stdc++.h> using namespace st ...
- java多线程并发(二)--线程的生命周期及方法详解
上篇随笔介绍了线程的相关基础知识以及新启线程的几种方法,本片将继续介绍线程的生命周期及方法详解. 一.线程的生命周期 在Thread代码中,线程的状态被分为6种 public enum State { ...
- 二十八、CI框架之自己写分页类,符合CI的路径规范
一.参照了CSDN上某个前辈写的一个CI分页类,自己删删改改仿写了一个类似的分页类,代码如下: 二.我们在模型里面写2个数据查询的函数,一个用于查询数据数量,一个用于查询出具体数据 三.我们在控制器里 ...
- POJ_3122 经典二分题
Pie Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8594 Accepted: 3124 Special Jud ...
- HZNU-ACM寒假集训Day10小结 单调栈-单调队列
数据结构往往可以在不改变主算法的前提下题高运行效率,具体做法可能千差万别,但思路却是有规律可循 经典问题:滑动窗口 单调队列O(n) POJ 2823 我开始写的: TLE 说明STL的库还是有点慢 ...
- maven的理解和使用
一.maven是什么? maven是项目管理工具 二.maven为什么要用? 在做开发的时候常常会用到外部的工具包(jar包),这就需要你一个一个的去他们的官网下工具包,然后在项目里依赖他们,比较的麻 ...
- Javascript里EQ、NE、GT、LT、GE、LE含义
EQ 就是 EQUAL等于 NE就是 NOT EQUAL不等于 GT 就是 GREATER THAN大于 LT 就是 LESS THAN小于 GE 就是 GREATER THAN OR EQUAL ...
- Android进阶——多线程系列之wait、notify、sleep、join、yield、synchronized关键字、ReentrantLock锁
多线程一直是初学者最困惑的地方,每次看到一篇文章,觉得很有难度,就马上叉掉,不看了,我以前也是这样过来的.后来,我发现这样的态度不行,知难而退,永远进步不了.于是,我狠下心来看完别人的博客,尽管很难但 ...
- React之Redux知识点补充
一. reducer纯函数方便自动化测试 二.