pengzhou讲完之后留了几道题......

[HNOI2008]玩具装箱toy

bzoj 1010 传送门

洛谷P3195 传送门

设c[i]是题目中c[i]的前缀和。

手推一下状态转移方程,f[i]=f[k]+(i-k-1+c[i]-c[k]-L)^2

搞一搞,x[k]=k+c[k],y[k]=f[k]+(k+c[k]+l+1)^2

这道题斜率单调递增,用队列维护下凸包即可。

 1 #include<cstdio>
 2 #define ll long long
 3 
 4 int n,tk=1,pt=1;
 5 ll l;
 6 ll c[50005];
 7 ll f[50005];
 8 ll q[50005];
 9 
10 ll y(int p)
11 {
12     return (ll)(f[p]+(ll)(p+c[p]+l+1)*(ll)(p+c[p]+l+1));
13 }
14 
15 ll x(int p)
16 {
17     return (ll)(p+c[p]);
18 }
19 
20 int main()
21 {
22     scanf("%d%lld",&n,&l);
23     for(int i=1;i<=n;i++)scanf("%lld",&c[i]),c[i]+=c[i-1];
24     for(int i=1;i<=n;i++)
25     {
26         while(tk<pt&&y(q[tk+1])-y(q[tk])<=2ll*(x(i))*(x(q[tk+1])-x(q[tk])))q[tk++]=0;
27         f[i]=f[q[tk]]+((ll)(i-q[tk]-1)+c[i]-c[q[tk]]-l)*((ll)(i-q[tk]-1)+c[i]-c[q[tk]]-l);
28         while(tk<pt&&(y(q[pt])-y(i))*(x(q[pt-1])-x(q[pt]))<=(y(q[pt-1])-y(q[pt]))*(x(q[pt])-x(i)))q[pt--]=0;
29         q[++pt]=i;
30     }
31     printf("%lld",f[n]);
32 }
玩具装箱toy

相关文章: