[HNOI2008]玩具装箱TOY

题面:

https://www.lydsy.com/JudgeOnline/problem.php?id=1010

一道dp题,需要斜率优化。

代码:

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 50050
#define ll long long
int n;
ll c[N],s[N],l,f[N];
const ll inf = 9999999999999ll;
int q[N],h,t;
ll x(int i)
{
    return -s[i]-1ll*i;
}
ll y(int i)
{
    return f[i]+x(i)*x(i);
}
ll z(int i)
{
    return (-s[i]+l+1ll-(ll)i);
}
ll k(int i)
{
    return 2*z(i);
}
ll b(int i)
{
    return z(i)*z(i);
}
int main()
{
    scanf("%d%lld",&n,&l);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&c[i]);
        s[i] = s[i-1] + c[i];
        f[i] = inf;
    }
    for(int i=1;i<=n;i++)
    {
        while(h<t&&(y(q[h+1])-y(q[h]))<=(x(q[h+1])-x(q[h]))*k(i))h++;
        f[i] = y(q[h])-k(i)*x(q[h])+b(i);
        while(h<t&&(y(i)-y(q[t]))*(x(q[t])-x(q[t-1]))>=(y(q[t])-y(q[t-1]))*(x(i)-x(q[t])))t--;
        q[++t] = i;
    }
    printf("%lld\n",f[n]);
    return 0;
}

 

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

 

posted @ 2018-09-11 20:53  LiGuanlin  阅读(177)  评论(0编辑  收藏  举报