zoukankan      html  css  js  c++  java
  • HDU3507 Print Article(斜率优化+单调队列)

    大佬的斜率优化博客,写的很好

    https://www.cnblogs.com/orzzz/p/7885971.html

    DP的斜率优化同四边形优化和数据结构优化类似,都是用一种方法快速找到最优的状态转移,以到达优化的目的。一次O(n)转移可以变成log或者常数级别的。

    这个题斜率优化的步骤就是,比较不同的状态转移,写成斜率的形式,发现他们存在一个关系,只需要维护一个下凸的凸包结构,最优状态转移的点一定在这个凸包上,剔除了很多不可能是最优的状态转移点。这个题还存在一个单调性,维护单调队列即可,因为每次找到最优点前面的点都可在凸包上剔除。

    这个题算斜率优化的模板,思路推导就见上面的博客吧,我也不会搞LaTeX。

    1A代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int N=5e5+10;
    ll dp[N];
    ll a[N];
    ll pre[N];
    ll que[N];
    int n,m;
    ll get_up(int i,int j){
        return dp[j]+pre[j]*pre[j]-dp[i]-pre[i]*pre[i];
    }
    ll get_down(int i,int j){
        return pre[j]-pre[i];
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m)){
            pre[0]=0;
            for(int i=1;i<=n;i++){
                scanf("%lld",&a[i]);
                pre[i]=pre[i-1]+a[i];
            }
            int head=0,tail=0;
            que[tail]=0;
            for(int i=1;i<=n;i++){
                while(head<tail&&get_up(que[head],que[head+1])<=2*pre[i]*get_down(que[head],que[head+1]))
                    head++;
                    //找到一个最优的转移,时间复杂度为为常数,保证队列非空
                dp[i]=dp[que[head]]+(pre[i]-pre[que[head]])*(pre[i]-pre[que[head]])+m;
                while(head<tail&&get_up(que[tail],i)*get_down(que[tail-1],que[tail])<=get_up(que[tail-1],que[tail])*get_down(que[tail],i))
                    tail--;
                que[++tail]=i;
    
            }
            cout<<dp[n]<<endl;
        }
        return 0;
    }
    不疯魔不成活
  • 相关阅读:
    2018年全国多校算法寒假训练营练习比赛(第四场)
    STL中的map
    java异常处理
    过滤器与监听器原理详解
    cookie和session机制区别
    servlet运行原理
    $.ajax相关用法
    jdk源码库
    Tomcat 系统架构与设计模式,第 1 部分: 工作原理
    Tomcat源码分析(二)------ 一次完整请求的里里外外
  • 原文地址:https://www.cnblogs.com/gzr2018/p/11448195.html
Copyright © 2011-2022 走看看