zoukankan      html  css  js  c++  java
  • P3195 [HNOI2008] 玩具装箱(斜率优化DP)

    题目链接
    (d[i])为将前 (i) 个玩具装入箱中所需得最小费用
    容易得到动态转移方程:

    [d[i] = min(d[j] + (s[i]-s[j]+i-j-1-L)^2), (j<i) ]

    其中(s[i] = sum_1^iC[i]),普通DP复杂度为(O(n^2))。经过斜率优化后将变为(O(n))
    仔细观察我们便于表示可以令(f[i] = s[i]+i)
    那么式子变成了

    [d[i] = min(d[j] + (f[i]-f[j]-1-L)^2) ]

    我们讨论(j_1,j_2(1le j_1< j_2<i))决策,假设(j_2)要比(j_1)更优,那么有

    (d[j_1] + (f[i] -f[j_1]-1-L)^2 ge d[j_2]+(f[i]-f[j_2]-1-L)^2)

    展开后得到

    (d[j_1] + f[i]^2 - 2 imes f[i] imes (f[j_1]+1+L)+(f[j_1]+1+L)^2 ge d[j_2]+f[i]^2-2 imes f[i] imes (f[j_2]+1+L)+(f[j_2]+1+L)^2)

    移项后可得

    (2cdot f[i]ge {d[j_2]+(f[j_2]+1+L)^2-d[j_1]-(f[j_1]+1+L)^2 over f[j_2]-f[j_1]})

    (g[i] = f[i]+1+L), 则有

    (2cdot f[i]ge {(d[j_2]+g[j_2])-(d[j_1]+g[j_1])over f[j_2]-f[j_1]})

    所以用一个队列维护决策集,当(j_1<j_2),并且上式满足时,(j_1) 出队。
    又由于(f[i])(i)单调递增。所以计算(d[i])之后要将 (i) 入队时,要及时排除掉不可能作为决策的元素。
    如何计算?队尾的斜率也要满足单调性,保持跟(f[i])的单调性一致即可。

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 50010;
    typedef long long ll;
    typedef long double db;
    db c[N],d[N],f[N],s[N],g[N];
    int n,L;
    int q[N],l,r;
    db sqr(db x){return x * x;}
    db slope(int i,int j){
        return ((d[i] +  g[i]) - (d[j] + g[j])) / (f[i] - f[j]);
    }
    int main(){
        scanf("%d%d",&n,&L);
        l=r=1;
        for(int i=1;i<=n;i++){
    	    cin>>c[i];
    	    s[i]=s[i-1] + c[i];
    	    f[i] = s[i] + i;
    	    g[i] = (f[i] + 1 + L) * (f[i] + 1 + L);
        }
        g[0] = (ll)(1+L)*(1+L);//注意0号元素的g值初始化
        for(int i=1;i<=n;i++){
            while(l < r && slope(q[l],q[l+1]) < 2 * f[i])l++;
            int j = q[l];
            d[i] = d[j] + sqr(f[i]-f[j]-1-L);
            while(l < r && slope(q[r],q[r-1]) > slope(i,q[r-1]))r--;//满足队尾斜率单调性
            q[++r] = i;//入队
        }
        printf("%lld
    ",(ll)d[n]);
        return 0;
    }
    
  • 相关阅读:
    IntelliJ IDEA 常用快捷键
    solr4.5分组查询、统计功能介绍
    用于Lucene的各中文分词比较
    Lucene打分规则与Similarity模块详解
    Lucene
    tar中的参数 cvf,xvf,cvzf,zxvf的区别
    tmux 入门踩坑记录
    第一个shell脚本
    make 和 make install 的区别
    交叉编译
  • 原文地址:https://www.cnblogs.com/1625--H/p/11266927.html
Copyright © 2011-2022 走看看