• 斜率优化


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

    把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
     
      */
  • 相关阅读:
    mysql事务
    数据类型
    win10 开启全局代理
    高并发的一些思考
    多线程也不一定比单线程快
    单线程的JavaScript
    Vue2 响应式原理
    检查Object是否存在某个属性
    堆和栈
    LeetCode
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5784636.html
Copyright © 2020-2023  润新知