zoukankan      html  css  js  c++  java
  • 斜率dp

    HUD-3507
    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

    [(sum_{i=1}^kC_i)^2+M ]

    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
    

    很容易推出:(dp[i]=min(dp[j]+(s[i]-s[j])^2+M)) 其中(j<i)
    这样的不加优化的裸dp是(O(n^2))的,5e5的数据肯定爆了
    假设(k<j<i)
    如果对于dp[i], j 比 k 优,有
    (dp[j]+(s[i]-s[j])^2+M)<dp[k]+(s[i]-s[k])^2+M))

    (dp[j]+s[j]^2-(dp[k]+s[j]^2)<2s[i](s[j]-s[k]))

    设$$g(k,j)=frac{dp[j]+s[j]2-(dp[k]+s[j]2)}{2(s[j]-s[k])}<s[i]$$
    也就是$$frac{y2-y1}{x2-x1}<k$$
    如果(g(k,j)<s[i]),说明j比k优,且s[i]是递增的,j永远比k优
    如果(g(a,b)>g(b,c)) b永远不是较优的:

    1. (g(b,c)<=s[i]),c比b优或一样
    2. (g(b,c)>s[i]),b比c优但是a比b优,所以a优

    所以,可以用队列维护一个下凸包,为何不是栈呢,这点想了好久,如果j比k优,j永远比k优,所以没用的就扔了。

    #include<bits/stdc++.h>
    #include<iostream>
    using namespace std;
    template<class T> inline bool read(T &x){
        x=0;register char c=getchar();register bool f=0;
        while(!isdigit(c)){if(c==EOF)return false;f^=c=='-',c=getchar();}
        while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
        if(f)x=-x;
        return true;
    }
    typedef long long ll;
    const ll MAXN=5e5+8,inf=0x3f3f3f3f,mod=1e9+7;
    int n,m;
    int s[MAXN],dp[MAXN],cnt;
    int que[MAXN],l,r;//队列  [l,r)
    inline int dy(int a,int b){return dp[a]+s[a]*s[a]-dp[b]-s[b]*s[b];}
    inline int dx(int a,int b){return 2*(s[a]-s[b]);}//a>b,如果不是这样,返回负数,不等式要变号
    inline void up(int i,int j){dp[i]=dp[j]+(s[i]-s[j])*(s[i]-s[j])+m;}//用j更新i
    int main() {
        while(read(n)&&read(m)){
            for(int i=1;i<=n;++i){
                read(s[i]);
                s[i]+=s[i-1];
            }
            l=r=0;
            que[r++]=0;
            for(int i=1;i<=n;++i){
                while(l<r-1&&dy(que[l+1],que[l])<=s[i]*dx(que[l+1],que[l]))l++;//直接l++,而不是零时变量
                up(i,que[l]);
                while(l<r-1&&dy(que[r-1],que[r-2])*dx(i,que[r-1])>=dy(i,que[r-1])*dx(que[r-1],que[r-2]))r--;
                que[r++]=i;
            }printf("%d
    ",dp[n]);
        }
        return 0;
    }
    

    每个i入队一次,出队最多一次,所以是O(n)

  • 相关阅读:
    kindeditor扩展粘贴截图功能&修改图片上传路径并通过webapi上传图片到图片服务器
    解决VS2015 VBCSCompiler.exe 占用CPU100%的问题
    电商网站商品模型之商品详情页设计方案
    大三那年在某宝8块钱买的.NET视频决定了我的职业生涯
    单点登录改进版-使用ajax分发cookie避免重定向轮询
    可跨域的单点登录(SSO)实现方案【附.net代码】
    使用ANTS Performance Profiler&ANTS Memory Profiler工具分析IIS进程内存和CPU占用过高问题
    js封装的三级联动菜单(使用时只需要一行js代码)
    EF查询之性能优化技巧
    EF使用CodeFirst方式生成数据库&技巧经验
  • 原文地址:https://www.cnblogs.com/foursmonth/p/14155949.html
Copyright © 2011-2022 走看看