bzoj1010 [HNOI2008]玩具装箱toy

题目链接

斜率优化。。。

推式子QAQ

令:$sum_i$为$C_{1~i}$的前缀和 ,$f_i=sum_i+i$

显然:$dp_i=min\{k\in{[1,i-1]}dp_k+[f_i-f_k-(L-1)]\}$

最后得到:

若$k$比$j$对于$i$更优,则:

$[dp[k]+(f_k+L+1)^2-dp[j]+(f_j+L+1)^2]/[2\times(f_k-f_j)]\leqslant f_i$

然后斜率优化……

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<string>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<iostream>
 7 #define re(i,l,r) for(int i=(l);i<=(r);i++)
 8 using namespace std;
 9 typedef long long LL;
10 template <typename Q>
11 void inin(Q &ret)
12 {
13     ret=0;int f=0;char ch=getchar();
14     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
15     while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
16     ret=f?-ret:ret;
17 }
18 int n,L,c[50050],que[50050];
19 LL dp[50050],f[50050];
20 double ff(const double &a){return a*a;}
21 double k(int j,int k)
22 {
23     return (dp[k]+ff(f[k]+L+1)-dp[j]-ff(f[j]+L+1))/(2.*(f[k]-f[j]));
24 }
25 int main()
26 {
27     inin(n),inin(L);
28     re(i,1,n)inin(c[i]);
29     re(i,1,n)f[i]=f[i-1]+c[i];
30     re(i,1,n)f[i]+=i;
31     int l=1,r=0;que[++r]=0;
32     re(i,1,n)
33     {
34         while(l<r&&k(que[l],que[l+1])<=f[i])l++;
35         int t=que[l];
36         dp[i]=dp[t]+(f[i]-f[t]-L-1)*(f[i]-f[t]-L-1);
37         while(l<r&&k(que[r],i)<k(que[r-1],que[r]))r--;
38         que[++r]=i;
39     }
40     printf("%lld",dp[n]);
41     return 0;
42 }

 

posted @ 2016-03-31 18:00  HugeGun  阅读(185)  评论(0编辑  收藏  举报