题目背景
GD是一个热衷于寻求美好事物的人,一天他拿到了一个美丽的序列。
题目描述
为了研究这个序列的美丽程度,GD定义了一个序列的“美丽度”和“美丽系数”:对于这个序列的任意一个区间[l,r],这个区间的“美丽度”就是这个区间的长度与这个区间的最小值的乘积,而整个序列的“美丽系数”就是它的所有区间的“美丽度”的最大值。现在GD想要你帮忙计算这个序列的“美丽系数”。
输入输出格式
输入格式:
第一行一个整数n,代表序列中的元素个数。 第二行n个整数a1、a2„an,描述这个序列。
输出格式:
一行一个整数,代表这个序列的“美丽系数”。
输入输出样例
输入样例#1:
3
1 2 3
输出样例#1:
4
说明
样例解释 选取区间[2,3],可以获得最大“美丽系数”为2*2=4。 数据范围 对于20%的数据,n<=2000; 对于60%的数据,n<=200000; 对于100%的数据,1<=n<=2000000,0<=ai<=2000000。 提示 你可能需要一个读入优化。
此题单调栈要用结构体保存它的值和下标.方便计算它管辖区间的长度.当之后有元素比它小时.它管辖的区间长度即此时的下标减去它之前的一个最小值的下标减1.(原因:不算这个位置和前一个最小值的位置).最后还要遍历栈.此时每一个元素的管辖区间的右端点均为N.故区间长度为N减该元素进栈时的下标., 看文字理解起来不太明白,带入代码蛮容易看懂
#include<iostream>
#include<string>
#include<string.h>
#include<vector>
#include<cstdio>
#include<stack>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2000006;
int n;
//st当栈用, 用反而stack不太方便
struct node
{
int d;
int p;
}a[maxn], st[maxn];
int main()
{
ios::sync_with_stdio(false);
cin >> n;
int top = 0;
ll res = 0; //保存结果的值, long long型
for (int i = 1; i <= n; i++)
{
cin >> a[i].d;
a[i].p = i;
if (!top) st[++top] = a[i]; //栈空, 直接入栈
else
{
while (st[top].d > a[i].d) //栈顶元素更大则出栈
{
//出栈时要判断出栈的值维护的区间的美丽度是否更大
res = max(res, (ll)st[top].d * (i - st[top - 1].p - 1));
//曾以为可以用(st[top].p - st[top - 1].p + 1)但top与i不一定相差为1
top--;
}
}
st[++top] = a[i];
}
//遍历栈
for (int i = 1; i <= top; i++)
res = max(res, (ll)(n - st[i - 1].p) * st[i].d);
cout << res << endl;
}