zoukankan      html  css  js  c++  java
  • 【BZOJ】【1010】【HNOI2008】玩具装箱Toy

    DP/斜率优化


      根据题目描述很容易列出动规方程:$$ f[i]=min{ f[j]+(s[i]-s[j]+i-j-1-L)^2 }$$

      其中 $$s[i]=sum_{k=1}^{i} c[k] $$

      而$x$即为$s[i]-s[j]+i-j-1$

      这个$x$的表示实在太不好看,我们容易发现$i-j$其实是可以跟$s[i]-s[j]$合到一起的,即令 $c[i]=c[i]+1$,则$s[i]=sum_{k=1}^{i} (c[i]+1)=sum_{k=1}^{i}c[i]+i $,所以$x=s[i]-s[j]-1$。再将那个$-1$与$L$合并,即$L=L+1$,然后我们就得到整理后的方程:$$ f[i]=min{ f[j]+(s[i]-s[j]-L)^2 } $$

      证明决策单调性:$( j > k )$

    [ egin{aligned} f[j]+(s[i]-s[j]-L)^2 &< f[k]+(s[i]-s[k]-L)^2 \ f[j]-f[k]+(s[j]^2-s[k]^2) &< 2*(s[i]-L)*(s[j]-s[k]) \ frac{ f[j]-f[k]+(s[j]^2-s[k]^2) }{ 2*(s[j]-s[k]) } &< s[i]-L end{aligned} ]

      这里将 $s[i]-L$ 当作一个整体来计算

     1 /**************************************************************
     2     Problem: 1010
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:132 ms
     7     Memory:2640 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 1010
    11 #include<cmath>
    12 #include<vector>
    13 #include<cstdio>
    14 #include<cstring>
    15 #include<cstdlib>
    16 #include<iostream>
    17 #include<algorithm>
    18 #define rep(i,n) for(int i=0;i<n;++i)
    19 #define F(i,j,n) for(int i=j;i<=n;++i)
    20 #define D(i,j,n) for(int i=j;i>=n;--i)
    21 #define pb push_back
    22 using namespace std;
    23 int getint(){
    24     int v=0,sign=1; char ch=getchar();
    25     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    26     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    27     return v*=sign;
    28 }
    29 const int N=50010;
    30 typedef long long LL;
    31 /******************tamplate*********************/
    32 LL c[N],s[N],f[N];
    33 int q[N],l,r;
    34 double slop(int k,int j){
    35     return double(f[j]+s[j]*s[j]-f[k]-s[k]*s[k])/
    36         double(2*(s[j]-s[k]));
    37 }
    38 int main(){
    39     int n=getint(),L=getint()+1;
    40     F(i,1,n){
    41         c[i]=getint()+1;
    42         s[i]=s[i-1]+c[i];
    43     }
    44     F(i,1,n){
    45         while(l<r && slop(q[l],q[l+1])<s[i]-L) l++;
    46         int t=q[l];
    47         f[i]=f[t]+(s[i]-s[t]-L)*(s[i]-s[t]-L);
    48         while(l<r && slop(q[r-1],q[r])>slop(q[r],i))r--;
    49         q[++r]=i;
    50     }
    51     printf("%lld
    ",f[n]);
    52     return 0;
    53 }
    View Code

    1010: [HNOI2008]玩具装箱toy

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 7156  Solved: 2714
    [Submit][Status][Discuss]

    Description

    P 教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京。他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维 容器中。P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的。 同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物,形式地说如果将第i件玩具到第j个玩具放到一个容器中,那么容器的长度 将为 x=j-i+Sigma(Ck) i<=K<=j 制作容器的费用与容器的长度有关,根据教授研究,如果容器长度为x,其制作费用为(X-L)^2.其中L是一个常量。P教授不关心容器的数目,他可以制作 出任意长度的容器,甚至超过L。但他希望费用最小.

    Input

    第一行输入两个整数N,L.接下来N行输入Ci.1<=N<=50000,1<=L,Ci<=10^7

    Output

    输出最小费用

    Sample Input

    5 4
    3
    4
    2
    1
    4

    Sample Output

    1

    HINT

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    常系数齐次线性递推
    【CF961G】Partitions(第二类斯特林数)
    【CF715E】Complete the Permutations(容斥,第一类斯特林数)
    【BZOJ4671】异或图(斯特林反演)
    【CF960G】Bandit Blues(第一类斯特林数,FFT)
    【BZOJ2159】Crash的文明世界(第二类斯特林数,动态规划)
    【LOJ#6374】网格(二项式反演,容斥)
    组合计数和反演
    有标号的DAG计数(FFT)
    [复习]多项式和生成函数相关内容
  • 原文地址:https://www.cnblogs.com/Tunix/p/4332984.html
Copyright © 2011-2022 走看看