BZOJ 1010 [Toys packing Toy]

Face questions

The meaning of problems

  One sequence \ (\ {a_n \} \ ) is divided into several segments, so that the first \ (I \) segment and to \ (S_I \) , the consideration of \ (\ sum (s_i-L ) ^ 2 \ ) , find the minimum cost.

answer

  Order \ (sum_i = \ sum_. 1} = {J ^ ia_j \) , with \ (dp_i \) on behalf of the former \ (I \) entry into the minimum cost several segments, then by definition:

\[ \begin{aligned} dp_i&=\min_{j=0}^{i-1}\{dp_j+(sum_i-sum_j-L)^2\}\\ &=\min_{j=0}^{i-1}\{dp_j+sum_i^2-2sum_i(sum_j+L))+(sum_j+L)^2\}\\ &=sum_i^2+\min_{j=0}^{i-1}\{(-2sum_j+L)sum_i+(dp_j+(sum_j+L)^2)\}\\ \end{aligned} \]

  After into the form of the last row, so \ (F_i (X) = (- 2sum_i + L) X + (dp_i + (sum_i + L) ^ 2) \) , then \ (dp_i = sum_i ^ 2 + \ min_ {j = 0 . 1-I ^ {}} F_j (sum_i) \) . Because of \ (f_i (x) \) is a linear function, and the slope \ (K_i <k_j (I <J) \) , it is possible to use a queue maintained a a \: (l f_i (x) \) on the convex hull constituted each first lookup on the convex hull \ (\ min_ ^ {J} = {0}. 1 I-F_j (sum_i) \) , then \ (l: f_i (x) \) was added in the convex hull.

  Because each interrogation incremented abscissa, the left end of the linear queue until it can pop up when asked \ (sum_i \) made in the convex hull at the minimum. When adding the linear queued right, which keeps popping straight left straight line is not left until completely covered before and after the two straight lines in the queue.


Code

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
typedef long double ld;
const int maxn=5e4+5;
struct line{
    ll a,b;
    line(ll a=0,ll b=0):a(a),b(b){}
};
line que[maxn];
int l,r;
inline bool check(const line &a,const line &b,const line &c){
    return (ld)c.a*(b.b-a.b)+(ld)c.b*(a.a-b.a)<=
           (ld)a.a*(b.b-a.b)+(ld)a.b*(a.a-b.a);
}
void add(const line &a){
    while (r-l>1&&check(que[r-2],que[r-1],a))
        r--;
    que[r++]=a;
}
ll get(ll x){
    while (r-l>1&&(ld)que[l].a*x+que[l].b>=(ld)que[l+1].a*x+que[l+1].b)
        l++;
    return que[l].a*x+que[l].b;
}
line make(ll sum,ll dp,int l){
    return line(-2*(sum+l),dp+(sum+l)*(sum+l));
}
int main(){
    int i,n,l,t;
    ll sum,dp;
    scanf("%d%d",&n,&l);
    l++;
    sum=0; add(make(0,0,l));
    for (i=0;i<n;i++){
        scanf("%d",&t);
        sum+=t+1;
        dp=get(sum)+sum*sum;
        add(make(sum,dp,l));
    }
    printf("%lld\n",dp);
    return 0;
}

Guess you like

Origin www.cnblogs.com/Kilo-5723/p/12039123.html