• [POJ 2796]Feel Good


    题目传送门problem_link

    题意:给出一个区间,选择这段区间的某个子区间,使得在这段子区间内的元素最小值*这段区间所有元素之和最大。

    具体看代码吧。

    #include <cstdio>
    #include <cstring>
    #include <stack>
    #include <iostream>
    using namespace std;
    #define N 100000 + 100
    int a[N], lef[N], sta[N], top;
    long long sum[N];
    stack<int> s;
    int main()
    {
        long long ans = -1, tmp;
        int n;
        int ll, rr;
    
        while (~scanf("%d", &n))
        {
            for (int i = 1; i <= n; i++)
            {
                scanf("%d", a + i);
                sum[i] = sum[i - 1] + a[i]; //前缀和预处理
            }
            a[++n] = -1;
            top = 0;
            for (int i = 1; i <= n; i++)
            {
                //维护的是一个单调增的栈(维护最小元素)
                if (s.empty() || a[i] > a[s.top()])
                {
                    s.push(i);
                    lef[i] = i; //记录第i个元素以自身为最小元素的左边界
                    continue;
                }
                if (a[i] == a[s.top()])
                    continue;
    
                int cur;
                //若出现比栈顶小的元素就一直出栈到大于栈顶元素为止
                while (!s.empty() && a[i] < a[s.top()])
                {
                    cur = s.top();s.pop();
                    //因为出栈,故记录出栈元素所在的区间和*自身(因为自身是这段区间的最小元素)
                    tmp = a[cur] * (sum[i - 1] - sum[lef[cur] - 1]);
                    if (tmp > ans)
                    {
                        //更新最大值,记录最左和最右下标
                        ll = lef[cur];
                        rr = i - 1;
                        ans = tmp;
                    }
                }
                //个人认为这里是单调栈最难理解的地方
                //将i重新入栈,并且将其以自身为最小元素的左边界更新到最后一个出栈元素的边界
                //要是不懂可以在纸上推一下,真的是很奇妙的东西
                //这可能就是所谓的算法艺术吧~
                lef[i] = lef[cur];
                s.push(i);
            }
    
            printf("%lld\n%d %d\n", ans, ll, rr);
        }
        return 0;
    
    }
  • 相关阅读:
    升级Xcode之后VVDocumenter-Xcode不能用的解决办法
    iOS国际化
    display:table 表格布局
    display: run-in
    连续字符换行 溢出点点点 多行省略
    Number 类型
    Boolean 相关
    Browsing contexts 浏览器上下文
    return flase 作用
    JS外链
  • 原文地址:https://www.cnblogs.com/Vikyanite/p/11380309.html
Copyright © 2020-2023  润新知