zoukankan      html  css  js  c++  java
  • POJ2796/DP/单调栈

    题目链接[http://poj.org/problem?id=2796]

    题意:给出一个数列,要求在这个数列里找到一个区间,使得在这个区间里的最小值*SUM[l,r]最大。

    题解:思路来源于【http://acm.hdu.edu.cn/showproblem.php?pid=1506】这个题。思想是:一a[i]为某个区间的最小值,初始区间为[i,i],左端向左延伸,右端向右延伸。最后维护最大值。

    但是向前向后延伸的时候不能暴力,时间不允许,这里要用到DP的思想:

    定义L[MAXN]=R[MAXN]=i;对于a[i]的L[i],刚开始的L[i]=i;如果a[i]>a[L[i]-1] -> L[i]=L[L[i]-1];2、R同理。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    const int MAXN = 100050;
    LL a[MAXN], sum[MAXN];
    LL L[MAXN], R[MAXN];
    int n;
    int main ()
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
        {
            scanf("%lld", &a[i]);
            sum[i] = sum[i - 1] + a[i];
            L[i] = R[i] = i;
        }
        a[0] = a[n + 1] = -1;//保证不会访问或者访问无效。
        for(int i = 1; i <= n; i++)
        {
            while(a[i] <= a[L[i] - 1])
                L[i] = L[L[i] - 1];
        }
        for(int i = n; i >= 1; i--)
        {
            while(a[i] <= a[R[i] + 1])
                R[i] = R[R[i] + 1];
        }
        LL ans = -1, l, r;
        for(int i = 1; i <= n; i++)
        {
            LL T = a[i] * (sum[R[i]] - sum[L[i] - 1]);
            if(ans < T)
                ans = T, l = L[i], r = R[i];
        }
        printf("%lld
    %lld %lld
    ", ans, l, r);
    }
    想的太多,做的太少。
  • 相关阅读:
    Graph 学习
    忘记 mysql 8.0 root 密码 怎么修改
    HTML字符实体(关于&nbsp;&gt;&lt;等)
    Sqlserver 中系统表sysobjects、syscolumns以及函数object_id
    SQL Server创建索引(转)
    改善SQL语句(转)
    (转)SqlServer索引及优化详解(1)
    标签点击不返回顶部和不刷新页面方法
    c#模拟js escape方法
    获取枚举描述信息
  • 原文地址:https://www.cnblogs.com/pealicx/p/6270632.html
Copyright © 2011-2022 走看看