题目链接 :

https://www.luogu.com.cn/problem/P2422

题目大意 :

每一天都有一个感受值,定义在一段区间 [ i , j ] 内的舒适程度为 [ i , j ] 区间内最小的感受值 * 区间内感受值的总和,求出最大的舒适程度。

思路 :

区间内感受值的总和可以通过 前缀和 求出。
区间内最小的感受值的求解可以转化,不去确定某个区间内的最小值,而是 确定最小值之后去找区间, 最小值已知,那区间的内所有值都会 大于 它,构造一个 递增的单调队列 ,找到左右第一个比假设最小值小的,两个值之间的区间最小值即是假设的值。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 100005;
LL ans, a[MAXN], l[MAXN], q[MAXN] = {0}, sum[MAXN], e = 0;
int n;
int main(){
	cin >> n;
	for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
	a[++n] = 0;
	for (int i = 1; i <= n; i++){
		sum[i] = sum[i - 1] + a[i];
		while (a[i] < a[q[e]]){
			l[q[e]] += (sum[i - 1] - sum[q[e]]);  //加上右侧的区间和,得到区间内感受值总和
			e--;
		}
		l[i] = sum[i] - sum[q[e]];  //左侧的区间和
		q[++e] = i;
	}
	for (int i = 1; i <= n; i++) ans = max(ans, l[i] * a[i]);
	cout << ans << "\n";
	return 0;
}
posted on 2021-09-05 13:39  Hamine  阅读(130)  评论(0编辑  收藏  举报