现在小V 要从中选取连续编号的礼物(即选取[l, r]内的礼物),使得获得的 happiness 最大。
[l, r]内的 happiness 定义为:
([l, r]内所有礼物满意值的最小值)*([l, r]内所有礼物满意值的和) 小V 想知道他能获得的 happiness
最大是多少,你能帮帮他吗?★数据输入
第一行为一个正整数 n。
第二行为n 个整数 w[1], w[2], …, w[n]
其中:
对于 50%的数据:1<=n<=100, 0<=w[i]<=100
对于 80%的数据:1<=n<=1,000, 0<=w[i]<=1,000
对于 100%的数据:1<=n<=100,000, 0<=w[i]<=10,000
★数据输出
小 V能获得的最大 happiness值。
分析:
这道题之前有做过了,虽然题目背景不一样,但是其实考察的都是一样的,
不过另一道题目还要求求出左右端点,这道题不用
由于n是 1e5 的 因此算法复杂度不能是 O(n^2)
不过这道题数据比较水,所以其实O(n^2)也能过,
下面是分析
可以参考我的另一个博客
https://blog.csdn.net/Inuyasha__/article/details/103247169
代码如下:
#include<bits/stdc++.h>
#define LL long long
#define ms(s) memset(s, 0, sizeof(s))
#define REP(i, a, b) for(int i = (a); i < (b); i++)
#define INF 0X7fffffff
using namespace std;
const int maxn = 1e6 + 10;
LL a[maxn];
LL sum[maxn];
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
for(int i = 0; i < n; i++) {
cin >> a[i];
if(i) sum[i] = sum[i - 1] + a[i];
else sum[i] = a[i];
}
a[n] = 0;
int i = 0;
LL ans = 0;
stack<LL> s;
while(i <= n) {
if(s.empty() || a[s.top()] <= a[i]) {
s.push(i++);
} else {
LL t = s.top();
s.pop();
LL e;
if(s.empty()) {
e = sum[i - 1] * a[t];
}
else {
e = (sum[i - 1] - sum[s.top()]) * a[t];
}
if(e > ans) {
ans = e;
}
}
}
cout << ans << endl;
return 0;
}
来源:CSDN
作者:樂_smile
链接:https://blog.csdn.net/Inuyasha__/article/details/103462444