• POJ


    题目传送门:POJ - 2796 Feel Good 

    题目大意:

    给你一组个数组,需要你找到一段子区间的和乘上该区间的最小值是最大值。输出结果和区间

    分析:

    首先区间上的和可以使用前缀和,这样可以O(1)找到每个区间的和。现在需要考虑的便是每个区间

    对应的最小值,如果暴力则存在n2个区间,每个区间在找到最小值一定一定会超时。可以想到数组

    区间的最小值无非是数组原来的数,对于这n个数,可以看他向左右延伸的宽度,即在这个区间内

    一定是以该值为最小值。因此需要找到在该数左边部分第一个比他小的,在右边第一个比他小的,在

    这段区间内最小值均为该数。很显然可以维护一个单调递增的栈就可以求出结果。然后枚举n个最小

    值和对应区间和的乘积,取最大即可。

    代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<stack>
    using namespace std;
    const int MAX=100009;
    long long a[MAX];
    long long sum[MAX];
    int n,l[MAX],r[MAX];
    stack<int>st;
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            sum[0]=0;
            for(int i=1;i<=n;i++)scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];
            for(int i=1;i<=n;i++)
            {
                while(!st.empty()&&a[st.top()] >= a[i])     
                {
                    r[st.top()] = i-1;//当前插入a[i]的数值比栈顶元素小,因此栈顶元素向右只能扩展到
                                     //i-1这个位置,因为过了i,最小值就变为a[i]了,所以记录栈顶元素
                                     //向右扩展的边界 
                    st.pop();
                }
                
                if(st.empty())l[i]=1;//因为是单调递增栈,因此新插入元素a[i]左端元素是比插入的元素小的 
                else l[i]=st.top()+1;//因此他向左扩展的值就是st.top()+1 
                st.push(i);
            }
            while(!st.empty())        //将剩余的元素一次弹出,并且每个元素向右都能扩展至最后一个元素 
            {
                r[st.top()]=n;
                st.pop();
            }
            long long ans=0;
            int id=-1;
            for(int i=1;i<=n;i++)//枚举求结果 
            {
                if(ans<=(sum[r[i]]-sum[l[i]-1])*a[i])
                {
                    ans=(sum[r[i]]-sum[l[i]-1])*a[i];
                    id=i;
                }
            }
            printf("%I64d
    ",ans);
            printf("%d %d
    ",l[id],r[id]);
        }
    
        return 0;
    }
  • 相关阅读:
    类的再理解
    关于网络配置和zmp以及json
    PCL 库安装
    Ros学习注意点
    Ros集成开发环境配置
    《TCP/IP详解卷1:协议》第3章 IP:网际协议(1)-读书笔记
    《Effective C++》第1章 让自己习惯C++-读书笔记
    《TCP/IP详解卷1:协议》第2章 链路层-读书笔记
    《TCP/IP详解卷1:协议》第1章 概述-读书笔记
    C++内存分配与对象构造的分离
  • 原文地址:https://www.cnblogs.com/LjwCarrot/p/11271782.html
Copyright © 2020-2023  润新知