zoukankan      html  css  js  c++  java
  • 斜率优化

    肛道理,斜率优化就是一种数形结合的思想啦。

    把dp方程写出来,然后维护凸包即可。

    hdu 3507

    Print Article

    Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
    Total Submission(s): 9555    Accepted Submission(s): 3012


    Problem Description
    Zero has an old printer that doesn't work well sometimes. As it is antique, he still like to use it to print articles. But it is too old to work for a long time and it will certainly wear and tear, so Zero use a cost to evaluate this degree.
    One day Zero want to print an article which has N words, and each word i has a cost Ci to be printed. Also, Zero know that print k words in one line will cost

    M is a const number.
    Now Zero want to know the minimum cost in order to arrange the article perfectly.
     
    Input
    There are many test cases. For each test case, There are two numbers N and M in the first line (0 ≤ n ≤ 500000, 0 ≤ M ≤ 1000). Then, there are N numbers in the next 2 to N + 1 lines. Input are terminated by EOF.
     
    Output
    A single number, meaning the mininum cost to print the article.
     
    Sample Input
    5 5 5 9 5 7 5
     
    Sample Output
    230
     
    //
    //  main.cpp
    //  hdu3507
    //
    //  Created by New_Life on 16/8/18.
    //  Copyright © 2016年 chenhuan001. All rights reserved.
    //
    
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 500500
    
    int s[N];
    
    /******************_单调队列模板_******************/
    //基于单调队列功能的单一性:以limit为序查找在一定范围内的极值。
    //复杂度:O(n)
    //用法: 创建的时候调用.init()
    //      插入队列:.push( Q_Node( KEY,LIMIT ) );
    //      设置limit值:.setlimit( LIMIT );
    //      查询<limit值的最大元素: Q_Node qn; q2.top(qn);
    //      再查询前需要设置limit值,如果队列为空返回false,否则将最大元素存入qn中并返回true
    
    struct Q_Node {
        int key,limit;//用来比较大小的key和控制存在时间的limit
        Q_Node(){}
        Q_Node(int _key,int _limit){ key=_key,limit=_limit; }
    };
    
    
    struct Q_Que {
        Q_Node Q[N];
        int qf,qd;
        int limit;// <limit 的元素将被弹出
        void init() {
            qf = qd = 0;//将队列内元素清空
        }
        
        void push(Q_Node newnode,int sj) {
            
            if(qf>qd && Q[qf-1].limit == newnode.limit)//斜率相同取key最小
            {
                Q[qf-1].key = min(Q[qf-1].key,newnode.key);
                return ;
            }
            
            while (qf>qd+1 &&  (Q[qf-2].key-Q[qf-1].key)*(Q[qf-2].limit-newnode.limit) >= (Q[qf-2].key-newnode.key)*(Q[qf-2].limit-Q[qf-1].limit) )//维护凸包
            {
                qf--;
            }
            
            Q[qf++] = newnode;
        }
        
        void setlimit(int _limit) {
            limit = _limit;
        }
        
        /*
         取出队列中>=limit且key最大的元素。
         */
        bool top(Q_Node &rt,int sj)
        {
            if(qf==qd+1)
            {
                rt = Q[qd];
                return true;
            }
            while(qf>qd+1 && Q[qd].key-sj*Q[qd].limit >= Q[qd+1].key-sj*Q[qd+1].limit) qd++;
            if(qf==qd) return false;
            rt = Q[qd];
            return true;
        }
    }q1;
    
    int dp[N];
    
    
    int main() {
        int n,m;
        while (cin>>n>>m) {
            q1.init();
            s[0] = dp[0] = 0;
            for(int i=1;i<=n;i++)
            {
                int tmp;
                scanf("%d",&tmp);
                s[i] = s[i-1]+tmp;
            }
            
            q1.push(Q_Node(0,0), 0);
            for(int i=1;i<=n;i++)
            {
                //先push
                Q_Node qn;
                q1.top(qn, s[i]);
                dp[i] = qn.key-s[i]*qn.limit+s[i]*s[i]+m;
                //cout<<dp[i]<<endl;
                if(i != n)
                    q1.push( Q_Node(dp[i]+s[i]*s[i],2*s[i]), s[i+1]);
            }
            printf("%d
    ",dp[n]);
        }
        return 0;
    }
    /*
     5 12
     5
     9
     5
     7
     5
     20 345
     12
     33
     22
     4
     5
     3
     6
     54
     123
     2
     34
     543
     1
     3
     1
     1
     6
     4
     2
     11
     
     10 345
     123
     2
     34
     543
     1
     3
     1
     1
     6
     4
     
      */
  • 相关阅读:
    GPS授时服务器(卫星同步时钟)科普小知识
    GPS和北斗卫星授时技术在时频领域的应用和发展
    NTP时间同步服务器(NTP时间服务器)在北京邮电大学的应用案例
    北斗时钟源(GPS网络时钟源)在校园网络应用
    NTP时钟源(GPS时间源)介绍与分析 安徽京准电子科技
    搭建ntp时间服务器并配置集群自动时钟同步
    GPS北斗网络时间源在内网域控制器上的设置方法
    肺炎疫情过后最想干的几件事
    提升苏州城市地位的几个建议
    江苏省如要打造一线城市,很简单!
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5784636.html
Copyright © 2011-2022 走看看