数据结构 栈 happiness

跟風遠走 提交于 2019-12-09 19:53:33

现在小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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!