bzoj1010: [HNOI2008]玩具装箱toy(斜率优化DP)

  codevs也有这题,伪·双倍经验233

  首先朴素DP方程很容易看出:f[i]=min(f[j]+(i-j-1+sum[i]-sum[j]-L)^2);

  于是设g[i]=i+sum[i]

     g[j]=j+sum[j]

     c=1+L

  则f[i]=min(f[j]+(g[i]-g[j]-c)^2)

  证明决策单调性,假设 j 比 k 优  

     f[j]+(g[i]-g[j]-c)^2<f[k]+(g[i]-g[k]-c)^2

   证明f[j]+(g[x]-g[j]-c)^2<f[k]+(g[x]-g[k]-c)^2

     f[j]+(g[i]+y-g[j]-c)^2<f[k]+(g[i]+y-g[k]-c)^2

     f[j]+(g[i]-g[j]-c)^2-2*y*(g[i]-g[j]-c)<f[k]+(g[i]-g[k]-c)^2-2*y*(g[i]-g[k]-c)

     g[j]>g[k]

  所以当 j > k 时,j 比 k 优,则 j 一直比 k 优。

  然后就可以斜率优化啦

     f[j]+(g[i]-g[j]-c)^2<f[k]+(g[i]-g[k]-c)^2

     f[j]-2*g[i]*(g[j]+c)+(g[j]+c)^2<f[k]-2*g[i]*(g[k]+c)+(g[k]+c)^2  

     (f[j]+(g[j]+c)^2-f[k]-(g[k]+c)^2)/(2*(g[k]-g[j]))<g[i]

  所以斜率是递增的,维护个下凸包

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#define ll long long
using namespace std;
const int maxn=500010;
int l,r;
ll n,L,sum[maxn],g[maxn],q[maxn],f[maxn];
void read(ll &k)
{
    int f=1;k=0;char c=getchar();
    while(c<‘0‘||c>‘9‘)c==‘-‘&&(f=-1),c=getchar();
    while(c<=‘9‘&&c>=‘0‘)k=k*10+c-‘0‘,c=getchar();
    k*=f;
}
ll sqr(ll x){return x*x;}
ll xl(int j,int k){return (f[j]+sqr(g[j]+1+L)-f[k]-sqr(g[k]+1+L))/(2*(g[j]-g[k]));}
int main()
{
    read(n);read(L);
    for(int i=1;i<=n;i++)
    read(sum[i]),sum[i]+=sum[i-1];
    for(int i=1;i<=n;i++)
    {
        g[i]=i+sum[i];
        while(l<r&&xl(q[l],q[l+1])<g[i])l++;
        f[i]=f[q[l]]+sqr(g[i]-g[q[l]]-1-L);
        while(l<r&&xl(q[r],q[r-1])>xl(i,q[r]))r--;
        q[++r]=i;
    }
    printf("%lld\n",f[n]);
}

 

时间: 2024-10-16 16:15:59

bzoj1010: [HNOI2008]玩具装箱toy(斜率优化DP)的相关文章

BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP

1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的.同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物,形式地说如果将第i件玩具到第j个玩具放到一个容器中,那么容器

[BZOJ1010] [HNOI2008] 玩具装箱toy (斜率优化)

Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的.同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物,形式地说如果将第i件玩具到第j个玩具放到一个容器中,那么容器的长度将为 x=j-i+Sigma(Ck) i<

HNOI2008玩具装箱 (斜率优化)

总算A了,心情好激动-- 如果会了一类斜率优化,基本上这类题就成了套模版了-- 只是k函数不同 1 var n,l,x,tail,head,m:int64; 2 i,j:longint; 3 dp,q,s:array[0..100000] of int64; 4 function k(x,y:longint):double; 5 begin 6 k:=1.0*((dp[x]+s[x]*s[x]-dp[y]-s[y]*s[y])/(s[x]-s[y])); 7 end; 8 procedure m

【斜率优化】BZOJ1010 [HNOI2008]玩具装箱toy

[题目大意] P教授有编号为1...N的N件玩具,第i件玩具长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的.如果将第i件玩具到第j个玩具放到一 个容器中,那么容器的长度将为 x=j-i+Sigma(Ck) i<=K<=j 制作容器的费用与容器的长度有关, 如果容器长度为x,其制作费用为(X-L)^2.其中L是一个常量.求最小费用. [思路] 懒得说了,把WC宋新波老师的课件搬运一下. 宋新波老师讲的很好,WC的时候第一次听斜率优化听他讲完秒懂了,时隔几个月再来消化一下.

BZOJ1010:[HNOI2008] 玩具装箱toy(斜率优化)

题意 求将一个长为\(n\)的序列(每个数为\(c_i\))分为很多段,每段(\(i\)~\(j\))的花费是\((j-i+\sum_{k=i}^{j}c_k-L)^2\),求最小的花费.(\(n<=50000\)) 题解 容易看出\(dp\)式子如下 \(dp[i]=min\{dp[j]+(sum[i]-sum[j]+i-(j+1)-L)^2\} \quad (j < i)\) 这个式子为\(O(n^2)\)的复杂度,显然过不去,我们进行一下斜率优化就能优化一维枚举决策点的复杂度,变成\(O

BZOJ1010: [HNOI2008]玩具装箱toy

[传送门:BZOJ1010] 简要题意: 给出n条连续线段,每条线段都有长度为x[i],我们可以把连续若干条线段连在一起,变成一个组合,两条线段如果相连,就要在两条线段中间添加一个长度为1的格子(如果没有相连就不用添加),假如我们现在选择把第i条到第j条线段之间的所有线段变成一组合的话,这个组合的总长度就为:x[i]+x[i+1]+x[i+2]+x[i+3]+...+x[j]+j-i,现在给出一个常数L,假设当前选择的组合的长度为s,那么这个组合就为我们产生了(s-L)^2的费用,求出把n条线段

bzoj 1010 玩具装箱toy -斜率优化

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

BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]

1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9812  Solved: 3978[Submit][Status][Discuss] Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P

BZOJ 1010: [HNOI2008]玩具装箱toy(DP+斜率优化)

[HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的.同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物,形式地说如果将第i件玩具到第j个玩具放到一个容器中,那么容器的长度将为